2010-10-01 143 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; 
    } 
} 

您可以看到它懶洋洋地評估源碼流。