LINQ, Where () vs FindAll ()

Respuestas:

203

FindAll()es una función en el List<T>tipo, no es un método de extensión LINQ como Where. Los métodos de extensión LINQ funcionan en cualquier tipo que implemente IEnumerable, mientras FindAllque solo pueden usarse en List<T>instancias (o instancias de clases que heredan de él, por supuesto).

Además, difieren en su propósito real. Wheredevuelve una instancia de IEnumerableque se ejecuta bajo demanda cuando se enumera el objeto. FindAlldevuelve un nuevo List<T>que contiene los elementos solicitados. FindAlles más como llamar Where(...).ToList()a una instancia de IEnumerable.

Adam Robinson
fuente
20
Sí, ¿Dónde está una versión lenta de findall
Pierreten
2
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 explica las diferencias entre la ejecución diferida (diferida) y la inmediata. Básicamente, en algunos casos, no necesita la lista completa, es posible que desee recorrer los elementos hasta que ocurra algo y luego detenerse. Aquí es donde la pereza es útil, pero dependiendo de la implementación, puede conducir a resultados impredecibles (todo explicado en el enlace). Espero que esto ayude.
nurchi
10

La mayor diferencia para mí es que .FindAll también está disponible en .Net 2.0. No siempre tengo el lujo de programar en .Net 3.5, así que trato de recordar los métodos 'nativos' de las colecciones genéricas .Net.

Sucedió varias veces que implementé un método de Lista ya disponible porque no pude LINQ.

Lo que encuentro útil en este caso es que, usando VS2008, puedo usar la inferencia de tipos y la sintaxis lambda. Estas son características del compilador, no características del marco. Esto significa que puedo escribir esto y aún permanecer dentro de .Net 2.0:

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

Pero si tiene LINQ disponible, es importante mantener la diferencia entre la ejecución diferida y la ejecución inmediata.

cfern
fuente
6

Si recuerdo correctamente, la principal diferencia (además de en qué están implementados: IEnumerable<T>vs. List<T>) es que Whereimplementa la ejecución diferida, donde en realidad no realiza la búsqueda hasta que la necesite, usándola en un bucle foreach, por ejemplo. FindAllEs un método de ejecución inmediata.

WayneC
fuente
3

Hice algunas pruebas en una lista de objetos de 80K y descubrí que Find()puede ser hasta un 1000% más rápido que usar un Wherecon FirstOrDefault(). No lo supe hasta que probé un temporizador antes y después de cada llamada. A veces era al mismo tiempo, otras veces era más rápido.

digiben
fuente
55
¿Intentaste acceder a la colección también? Enumerable.Where () utiliza la ejecución diferida y no se evalúa antes de acceder a la colección, lo que podría conducir a falsas concepciones sobre si es realmente más rápido o no. Aún así, en su mayor parte, generalmente es más rápido usar enumerables en lugar de colecciones estáticas (como Tipo <T> y Array <T>).
Sebastian Job Bjørnager Jensen
La pregunta es sobre FindAll. Es obvio que Find será más rápido que Where (tomando todos los valores) y obteniendo FirstOrDefault
Vivek MVK