LinqでCast()およびOftype()を使用する場合


211

Linq IEnumerableから型をキャストする2つの方法を知っArraylistており、どの場合にそれらを使用するのか疑問に思いますか?

例えば

IEnumerable<string> someCollection = arrayList.OfType<string>()

または

IEnumerable<string> someCollection = arrayList.Cast<string>()

これらの2つの方法の違いは何ですか?どこに適用する必要がありますか?

回答:


322

OfType-タイプxに安全にキャストできる要素のみを返します。
Cast-すべての要素をタイプxにキャストしようとします。それらのいくつかがこのタイプのものでない場合は、InvalidCastException


たとえば編集

object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }

1
そのために乾杯。事前に両方を試してみましたが、どちらも予想されるタイプの要素がすべて含まれていたため、違いがわかりませんでした。

6
@SLaks Cast<T>は、コレクションに型T要素のみが含まれていることが確実である場合に使用する必要があることを正しく指摘しています。型チェックのOfType<T>ために遅くなりますis。コレクションは型である場合はIEnumerable<T>Cast<T>単にコレクション全体をキャストしますIEnumerable<T>し、それを列挙避けます。OfType<T>まだ列挙されます。REF:stackoverflow.com/questions/11430570/...
ヒッピー

23
.Cast<string>()列挙してもスローされない場合でも、と同等ではありません.OfType<string>()。その理由は、nullは常にによってスキップされるためです.OfType<TResult>()。例:new System.Collections.ArrayList { "abc", "def", null, "ghi", }.OfType<string>().Count()のみを与える3; と同様の式はに.Cast<string>()評価され4ます。
Jeppe Stig Nielsen

1
言い換えれば、「as」演算子と「cast」演算子の違いのようなものです
faza

111

http://solutionizing.net/2009/01/18/linq-tip-enumerable-oftype/

基本的に、Cast()は次のように実装されます。

public IEnumerable<T> Cast<T>(this IEnumerable source)
{
  foreach(object o in source)
    yield return (T) o;
}

明示的なキャストを使用するとパフォーマンスは向上しますが、キャストが失敗した場合はInvalidCastExceptionが発生します。このアイデアのあまり効率的ではないが有用なバリエーションは、OfType()です。

public IEnumerable<T> OfType<T>(this IEnumerable source)
{
  foreach(object o in source)
    if(o is T)
      yield return (T) o;
}

返される列挙には、指定した型に安全にキャストできる要素のみが含まれます。


38

Cast<string>()すべてのアイテムがstrings であることがわかっている場合は、呼び出す必要があります。
それらの一部が文字列でない場合は、例外が発生します。

OfType<string>()一部のアイテムがstringsではなく、それらのアイテムが必要ないことがわかっている場合は、呼び出す必要があります。
それらの一部が文字列でない場合、新しいには含まれませんIEnumerable<string>


1
この回答は、(現在)どの方法を使用するかを明示的にアドバイスする唯一の回答です。
CodeFox

4

それは注意しなければならないCast(Of T)上で使用することができIEnumerable、次のような非ジェネリックコレクションまたはリストにLINQを使用する必要がある場合は、これまでありますので、もし、とは異なり、他のLINQの機能ArrayListは、使用することができますCast(Of T)し、キャストにIEnumerable(Of T)LINQが作業できる場所。


2

Cast()コレクションのすべての要素をキャストしようとします(要素のタイプが間違っている場合は例外をスローします)OfType()が、適切なタイプの要素のみを返します。


2

OfType要素をフィルタリングして、指定したタイプの要素のみを返します。 Cast要素をターゲットタイプにキャストできない場合はクラッシュします。


2

Cast<T>すべてのアイテムを指定されたタイプにキャストしようとしTます。このキャストは失敗するか、例外をスローする可能性があります。OfType<T>元のコレクションのサブセットを返し、タイプのオブジェクトのみを返しますT

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.