LINQ, Où () vs FindAll ()

Réponses:

203

FindAll()est une fonction sur le List<T>type, ce n'est pas une méthode d'extension LINQ comme Where. Les méthodes d'extension LINQ fonctionnent sur tous les types qui implémentent IEnumerable, alors qu'elles FindAllne peuvent être utilisées que sur des List<T>instances (ou des instances de classes qui en héritent, bien sûr).

En outre, ils diffèrent par leur objectif réel. Whererenvoie une instance de IEnumerablequi est exécutée à la demande lorsque l'objet est énuméré. FindAllrenvoie un nouveau List<T>contenant les éléments demandés. FindAllest plus comme appeler Where(...).ToList()une instance de IEnumerable.

Adam Robinson
la source
20
Oui, où est une version paresseuse de findall
Pierreten
2
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 explique les différences entre l'exécution différée (différée) et immédiate. En gros, dans certains cas, vous n'avez pas besoin de la liste entière, vous pouvez vouloir parcourir les éléments jusqu'à ce que quelque chose se passe, puis vous arrêter. C'est là que la paresse est utile, mais en fonction de la mise en œuvre, peut conduire à des résultats imprévisibles (tous expliqués dans le lien). J'espère que cela t'aides.
nurchi
10

La plus grande différence pour moi est que .FindAll est également disponible dans .Net 2.0. Je n'ai pas toujours le luxe de programmer en .Net 3.5, j'essaie donc de me souvenir des méthodes «natives» des collections génériques .Net.

Il m'est arrivé plusieurs fois que j'ai moi-même implémenté une méthode List déjà disponible car je ne pouvais pas la LINQ.

Ce que je trouve pratique dans ce cas, c'est que, en utilisant VS2008, je peux utiliser l'inférence de type et la syntaxe lambda. Ce sont des fonctionnalités du compilateur, pas des fonctionnalités du framework. Cela signifie que je peux écrire ceci tout en restant dans .Net 2.0:

var myOddNums = myNums.FindAll(n => n%2==1);

Mais si vous disposez de LINQ, il est important de garder la différence entre l'exécution différée et l'exécution immédiate.

cfern
la source
6

Si je me souviens bien, la principale différence (en plus de ce sur quoi ils sont implémentés: IEnumerable<T>vs. List<T>) est qu'il Whereimplémente une exécution différée, où il ne fait pas la recherche jusqu'à ce que vous en ayez besoin - en l'utilisant dans une boucle foreach par exemple. FindAllest une méthode d'exécution immédiate.

WayneC
la source
3

J'ai fait quelques tests sur une liste d'objets de 80K et j'ai trouvé que cela Find()pouvait être jusqu'à 1000% plus rapide que d'utiliser un Whereavec FirstOrDefault(). Je ne savais pas cela avant de tester une minuterie avant et après chaque appel. Parfois c'était le même temps, d'autres fois c'était plus rapide.

digiben
la source
5
Avez-vous également essayé d'accéder à la collection? Enumerable.Where () utilise une exécution différée et n'est pas évaluée avant l'accès à la collection, ce qui pourrait conduire à de fausses conceptions quant à savoir si elle est réellement plus rapide ou non. Pourtant, il est généralement plus rapide d'utiliser des énumérables plutôt que des collections statiques (comme Type <T> et Array <T>).
Sebastian Job Bjørnager Jensen
La question concerne FindAll. Il est évident que Find sera plus rapide que Where (en prenant toutes les valeurs) et d'obtenir le FirstOrDefault
Vivek MVK