LINQ, Where () vs FindAll ()

Respostas:

202

FindAll()é uma função do List<T>tipo, não é como um método de extensão LINQ Where. Os métodos de extensão LINQ funcionam em qualquer tipo que implemente IEnumerable, enquanto que FindAllsó podem ser usados ​​em List<T>instâncias (ou instâncias de classes que herdam dela, é claro).

Além disso, eles diferem na finalidade real. Whereretorna uma instância IEnumerableexecutada sob demanda quando o objeto é enumerado. FindAllretorna um novo List<T>que contém os elementos solicitados. FindAllé mais como chamar Where(...).ToList()uma instância de IEnumerable.

Adam Robinson
fonte
20
Sim, Onde é uma versão preguiçosa de findall
Pierreten
2
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 explica as diferenças entre a execução lenta (adiada) e imediata. Basicamente, em alguns casos, você não precisa da lista inteira; talvez queira percorrer os itens até que algo aconteça e parar. É aqui que a preguiça é útil, mas, dependendo da implementação, pode levar a resultados imprevisíveis (todos explicados no link). Espero que isto ajude.
Nurchi 06/06/19
10

A maior diferença para mim é que .FindAll também está disponível no .Net 2.0. Nem sempre tenho o luxo de programar no .Net 3.5, por isso tento me lembrar dos métodos 'nativos' das coleções genéricas .Net.

Aconteceu várias vezes que eu implementei um método List já disponível porque não consegui LINQ.

O que acho útil nesse caso é que, usando o VS2008, posso usar a inferência de tipo e a sintaxe lambda. Esses são recursos do compilador, e não da estrutura. Isso significa que eu posso escrever isso e ainda permanecer no .Net 2.0:

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

Mas se você tiver o LINQ disponível, é importante manter a diferença entre execução adiada e execução imediata.

cfern
fonte
6

Se bem me lembro, a principal diferença (além do que eles são implementados em: IEnumerable<T>vs. List<T>) é que Whereimplementa a execução adiada, onde ela não faz a pesquisa até que você precise - usando-a em um loop foreach, por exemplo. FindAllé um método de execução imediata.

WayneC
fonte
3

Fiz alguns testes em uma lista de objetos de 80K e descobri que Find()pode ser até 1000% mais rápido do que usar um Wherecom FirstOrDefault(). Eu não sabia disso até testar um cronômetro antes e depois de cada chamada. Às vezes era a mesma hora, outras vezes era mais rápido.

digiben
fonte
5
Você tentou acessar a coleção também? Enumerable.Where () usa a execução adiada e não é avaliada antes do acesso à coleção, o que pode levar a falsas concepções sobre se é realmente mais rápido ou não. Ainda assim, é geralmente mais rápido usar enumeráveis ​​do que coleções estáticas (como Type <T> e Array <T>).
Sebastian Job Bjørnager Jensen
A pergunta é sobre FindAll. É óbvio que o Find será mais rápido do que Where (pegando todos os valores) e obtendo o FirstOrDefault
Vivek MVK