tags:

views:

77

answers:

3

Hi,

I have a collection which contains two type of objects 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());

Now I want to select the objects from the collection based on its type (A or B, not both).

How I can write a LINQ query for this? Please help me. Otherwise I need to loop through the collection, which I dont want to. Thanks.

Edit:

Thank you all for your help. Now I can use OfType() from LINQ. But I think in my case it wont work. My situation is

Class Container
{
  List<Base> bases;
}

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

Now I want to select the container from containers, which has at least one type A. May be this cant be done by LINQ. Thanks a lot.

+4  A: 

You can use the OfType Linq method for that:

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

Regarding your unwillingness to loop throught the collection, you should keep in mind that Linq does not do magic tricks; I didn't check the implementation of OfType, but I would be surprised not to find a loop or iterator in there.

Fredrik Mörk
Thanks Fredrik. I have one more question, if more than one person answered correctly, which answer I need to make as "Correct answer"?
Jai
@Jai: You should mark the answer that you found most useful or helpful. Both Jared and Fredrik are correct, but Fredrik's answer had more depth and may help you learn more.
Matthew Ferreira
@Jai: flip a coin? There is a coin-flipper here, if you need one: http://www.random.org/coins/?num=1)
Fredrik Mörk
+1, since I can't mark your answer as correct.
Matthew Ferreira
+1  A: 

You can use the OfType extension method for this

IEnumerable<A> filteredToA = list.OfType<A>();
IEnumerable<B> filteredToB = list.OfType<B>();
JaredPar
Thanks a ton JaredPar.
Jai
+1  A: 

For completeness, here is the source code of 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;
    } 
}

You can see that it lazily evaluates the source stream.

Drew Noakes