2010-10-01 102 views
33

我有包含两个类型的对象的& B.LINQ选择由类型的对象

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>(); 

现在我想从容器中选择容器,它至少有一个类型A.可能不能由LINQ完成。非常感谢。

+3

你可以展开你的编辑吗? “选择容器”是什么意思? – 2010-10-01 20:29:46

+0

或者只是创建一个新的问题.... – WoIIe 2015-08-06 12:44:17

回答

69

您可以使用该OfType LINQ的方法:

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

关于你不愿循环throught收集,你应该记住,LINQ的不把戏;我没有检查OfType的实现,但是我会惊讶地发现而不是在那里找到一个循环或迭代器。

+0

感谢Fredrik。我还有一个问题,如果不止一个人回答正确,我需要作出“正确答案”的答案? – jaks 2010-10-01 20:17:53

+2

@Jai:你应该标出你认为最有用或有用的答案。 Jared和Fredrik都是正确的,但Fredrik的回答更加深入,可以帮助你了解更多。 – 2010-10-01 20:21:30

+0

@Jai:翻转硬币?这里有一个硬币鳍状肢,如果你需要一个:http://www.random.org/coins/?num=1&cur=20-novelty.voting-2004 - 在我和@JaredPar之间找不到投币,所以你必须做好克里与布什的关系。我会留给你决定谁是谁;) – 2010-10-01 20:21:40

11

可以使用OfType扩展方法这个

IEnumerable<A> filteredToA = list.OfType<A>(); 
IEnumerable<B> filteredToB = list.OfType<B>(); 
+0

非常感谢JaredPar。 – jaks 2010-10-01 20:27:34

7

为了完整起见,这里是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; 
    } 
} 

您可以看到它懒洋洋地评估源码流。