web-dev-qa-db-ja.com

オブジェクトの種類によるLINQ選択

2つのタイプのオブジェクトAとBを含むコレクションがあります。

Class Base{}
Class A : Base {}
Class B : Base {}

List<Base> collection = new List<Base>();
collection.Add(new A());
collection.Add(new B());
collection.Add(new A());
collection.Add(new A());
collection.Add(new B());

次に、そのタイプ(両方ではなくAまたはB)に基づいてコレクションからオブジェクトを選択します。

このためにどのようにLINQクエリを書くことができますか?私を助けてください。そうでない場合、コレクションをループする必要がありますが、これはしたくないです。ありがとう。

編集:

ご協力ありがとうございます。これで、LINQのOfType()を使用できます。しかし、私の場合はうまくいかないと思います。私の状況は

Class Container
{
  List<Base> bases;
}

List<Container> containers = new List<Container>();

ここで、少なくとも1つのタイプAを持つコンテナーからコンテナーを選択します。これは、LINQで実行できない場合があります。どうもありがとう。

40
jaks

OfType Linqメソッドを使用できます:

var ofTypeA = collection.OfType<A>();

コレクションをループ処理したくないということについては、Linqは魔法のトリックを実行しないことに注意してください。 OfTypeの実装を確認しませんでしたが、そこでループまたはイテレータを見つけることに驚いたでしょうnot

84
Fredrik Mörk

これにはOfType拡張メソッドを使用できます

IEnumerable<A> filteredToA = list.OfType<A>();
IEnumerable<B> filteredToB = list.OfType<B>();
12
JaredPar

完全を期すために、ここにEnumerable.OfType<T>

public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source) {
    if (source == null) throw Error.ArgumentNull("source"); 
    return OfTypeIterator<TResult>(source); 
}

static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source) {
    foreach (object obj in source) {
        if (obj is TResult) yield return (TResult)obj;
    } 
}

ソースストリームを遅延評価することがわかります。

10
Drew Noakes