LINQ, Where () vs FindAll ()

Alguém pode explicar como funciona o LINQ Onde (..) e FindAll (..) diferem? Ambos parecem fazer a mesma coisa …

FindAll() é uma function no tipo List , não é um método de extensão LINQ como Where . Os methods de extensão LINQ funcionam em qualquer tipo que implemente IEnumerable , enquanto FindAll só pode ser usado em instâncias List (ou instâncias de classs que herdam dele, é claro).

Além disso, eles diferem no propósito real. Where retorna uma instância de IEnumerable que é executada sob demanda quando o object é enumerado. FindAll retorna uma nova List que contém os elementos solicitados. FindAll é mais como chamar Where(...).ToList() em uma instância de IEnumerable .

A maior diferença para mim é que o .FindAll também está disponível no .Net 2.0. Eu nem sempre tenho o luxo de programar em .Net 3.5, então eu tento lembrar os methods ‘nativos’ das collections genéricas .Net.

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

O que acho útil nesse caso é que, usando o VS2008, posso usar a inferência de tipos e a syntax lambda. Estes são resources de compilador, não resources de estrutura. Isso significa que posso escrever isso e ainda permanecer no .Net 2.0:

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

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

Se bem me lembro, a principal diferença (além do que é implementado em: IEnumerable vs. List ) é que Where implementa a execução adiada, onde ela não realiza a pesquisa até que você precise dela – usando-o em um loop foreach por exemplo. FindAll é um método de execução imediata.

Eu fiz alguns testes em uma lista de 80K objects e descobri que Find() pode ser até 1000% mais rápido do que usando um Where with FirstOrDefault() . Eu não sabia disso até testar um timer antes e depois de cada chamada. Às vezes era a mesma hora, outras vezes era mais rápido.