Comment puis-je filtrer les objets en fonction de leur type dérivé avec linq-to-objets?
Je cherche la solution avec les meilleures performances. P>
Les classes utilisées: P>
List<Animal> animals = new List<Animal> { new Cat(), new Dog(), new Duck(), new MadDuck(), }; // Get all animals except ducks (and or their derived types) var a = animals.Where(animal => (animal is Duck == false)); var b = animals.Except((IEnumerable<Animal>)animals.OfType<Duck>()); // Other suggestions var c = animals.Where(animal => animal.GetType() != typeof(Duck)) // Accepted solution var d = animals.Where(animal => !(animal is Duck));
4 Réponses :
sauf () code> est assez lourd. li>
-
Gardez à l'esprit que la solution est code> - retournerait vrai même certains Someduck code> Classe héritée de Duck code> P> P>
XXX PRE> LI>
Une autre solution pourrait être: p> xxx pré> ul>
Merci. J'ai inclus votre suggestion dans la question.
Si vous souhaitez exclure également les sous-classes de canard, le Sinon, la recommandation de GetType de SLL est la meilleure p> est code> est le meilleur. Vous pouvez raccourcir le code à juste
. Où (animal =>! (Animal est canard)); code> p>
Comme je souhaite exclure les sous-classes et que ceci est une notation plus courte et plus lisible, j'ai accepté votre réponse.
Je ne crois pas que ce battype
Si vous ne voulez pas canard code> ni aucune sous-classe de
Duck code> Pour être retourné, vous devez utiliser la méthode
isAssignAdFrom code>:
animals.Where(animal => !animal.GetType().IsAssignableFrom(typeof(Duck)));
Joli. Je n'ai jamais utilisé IsassignableFrom code> avant. Je me demande que la performance est pour cette méthode. Cela ressemble à un bon cas pour un profilage.
Je m'attendrais à ce qu'il soit aussi rapide qu'un comme code>, puis chèque null.
Selon () et vérification Tapez où () extension L'appel de l'Oftype est équivalent à votre option (a), bien que est Duck == True em>, donc basé sur cela, je dirais que je dirais que je dirais que je dirais que je dirais que je dirais que Stick to option (A) . p>
Et si vous avez un
madduk code>, qui hérite d'un
canard code>? Devrait-il être retourné ou non? Et, BTW, qu'essayez-vous d'atteindre? L'utilisation de
est code> et la vérification de type d'exécution peut indiquer des problèmes de conception.
Bonne question. Dans ce cas particulier, j'aimerais que les sous-classes du canard soient exclues aussi. Cela ferait mon option
B code> invalide alors qu'ils comparent le type mais pas l'héritage.
En ce qui concerne ma deuxième questien: à partir d'un point de vue OOP, d'autres parties de votre code ne doivent généralement pas être concernées par des types réels de vos objets. Le devrait savoir "le moins possible". C'est pourquoi je me demande pourquoi tu fais ça.
@Groo Il y a en effet un problème de conception dans le code fourni les données. Par conséquent, je dois supprimer des classes dérivées spécifiques pour «nettoyer» les données fournies.
@Marceljackwerth Bonne question. Je cherche la solution la mieux performante. J'ai édité la question à inclure cela.
@Aphelion: La vraie question est, puisque vous avez tous le code, à l'exception du
chronomètre code>, pourquoi vous avez demandé cela plutôt que de simplement comprendre les résultats de performance par vous-même.
@ Will Point pris. Merci. Maintenant que j'ai une liste d'options, le chronomètre est en effet la prochaine étape à suivre. En fait, j'ai mis à jour la question avec des suggestions supplémentaires que j'ai proventées des réponses de ma question initiale. A cette époque, je n'avais que 2 options suggérées. J'ai mis à jour la question pour les futures recherches (par d'autres utilisateurs) afin de pouvoir trouver l'option suggérée et la meilleure dans une liste simple.
@Aphelion: gotcha. Je ne sais pas si ça vaut le coup. En règle générale, une personne ayant une question similaire rechercherait et trouverait la vôtre, puis lisez les réponses. Donc, il n'y a pas beaucoup de besoin de modifier la question avec des détails des réponses ...