2010-10-01 3 views
33

j'ai une collection qui contient deux types d'objets A & B.sélection LINQ par type d'un objet

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

Maintenant, je veux sélectionner les objets à partir de la collection sur la base de son type (A ou B, pas les deux).

Comment puis-je écrire une requête LINQ pour cela? Aidez-moi, s'il vous plaît. Sinon, je dois parcourir la collection, ce que je ne veux pas. Merci.

Editer:

Merci à tous pour votre aide. Maintenant, je peux utiliser OfType() à partir de LINQ. Mais je pense que dans mon cas ça ne marchera pas. Ma situation est

Class Container 
{ 
    List<Base> bases; 
} 

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

Maintenant, je veux sélectionner le conteneur à partir de conteneurs, qui a au moins un type A. Peut-être ce ne peut pas être fait par LINQ. Merci beaucoup.

+3

Pourriez-vous développer votre montage? Que voulez-vous dire par "sélectionner le conteneur"? –

+0

Ou créez simplement une nouvelle question .... – WoIIe

Répondre

69

Vous pouvez utiliser la méthode Linq OfType pour que:

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

En ce qui concerne votre réticence à boucle throught la collection, vous devez garder à l'esprit que Linq ne fait pas des tours de magie; Je n'ai pas vérifié la mise en œuvre de OfType, mais je serais surpris pas de trouver une boucle ou un itérateur là-bas.

+0

Merci Fredrik. J'ai encore une question, si plus d'une personne a répondu correctement, quelle réponse dois-je faire comme "bonne réponse"? – jaks

+2

@Jai: Vous devez marquer la réponse que vous avez trouvée la plus utile ou utile. Les deux Jared et Fredrik ont ​​raison, mais la réponse de Fredrik avait plus de profondeur et pourrait vous aider à en savoir plus. –

+0

@Jai: lancer une pièce? Il y a un flipper ici, si vous en avez besoin: http://www.random.org/coins/?num=1&cur=20-novelty.voting-2004 - n'a pas pu trouver de pièce de vote entre moi et @JaredPar , donc vous devrez faire avec Kerry contre Bush. Je vais vous laisser décider qui est qui;) –

11

Vous pouvez utiliser la méthode d'extension OfType pour cette

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

Merci une tonne JaredPar. – jaks

7

Pour être complet, voici le code source de 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; 
    } 
} 

Vous pouvez voir qu'il évalue paresseusement le flux source.