Quelqu'un peut-il expliquer le fonctionnement des fonctions LINQ Où (..) et FindAll (..) diffèrent? Ils semblent tous les deux faire la même chose ...
FindAll()
est une fonction du type List<T>
, ce n'est pas une méthode d'extension LINQ comme Where
. Les méthodes d'extension LINQ fonctionnent sur tout type qui implémente IEnumerable
, alors que FindAll
ne peut être utilisé que sur des instances List<T>
(Ou des instances de classes qui en héritent, bien sûr).
En outre, ils diffèrent par leur objectif réel. Where
renvoie une instance de IEnumerable
exécutée à la demande lors de l'énumération de l'objet. FindAll
renvoie un nouveau List<T>
contenant les éléments demandés. FindAll
ressemble plus à appeler Where(...).ToList()
sur une instance de IEnumerable
.
La plus grande différence pour moi est que .FindAll est également disponible en .Net 2.0. Je n'ai pas toujours le luxe de programmer en .Net 3.5, alors j'essaie de me souvenir des méthodes "natives" des collections génériques .Net.
Il m'est arrivé à plusieurs reprises d'implémenter moi-même une méthode List déjà disponible parce que je ne pouvais pas le LINQ.
Ce que je trouve pratique dans ce cas-ci, c’est que, avec VS2008, I can utilise 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 avez LINQ disponible, il est important de conserver la différence entre exécution différée et exécution immédiate.
Si je me souviens bien, la différence principale (à part ce sur quoi elles sont implémentées: IEnumerable<T>
contre. List<T>
) est que Where
implémente une exécution différée, où il ne fait pas la recherche tant que vous n’en avez pas besoin - en l’utilisant dans une boucle foreach par exemple. FindAll
est une méthode d'exécution immédiate.
J'ai fait quelques tests sur une liste d'objets de 80K et j'ai découvert que Find()
pouvait être jusqu'à 1000% plus rapide que d'utiliser un Where
avec FirstOrDefault()
. Je ne savais pas cela avant de tester une minuterie avant et après chaque appel. Parfois, c'était à la même heure, d'autres fois, c'était plus rapide.