Qualcuno può spiegare come funzionano le funzioni LINQ Where (..) e FindAll (..)? Entrambi sembrano fare la stessa cosa ...
Qualcuno può spiegare come funzionano le funzioni LINQ Where (..) e FindAll (..)? Entrambi sembrano fare la stessa cosa ...
Risposte:
FindAll()
è una funzione sul List<T>
tipo, non è un metodo di estensione LINQ come Where
. I metodi di estensione LINQ funzionano su qualsiasi tipo che implementa IEnumerable
, mentre FindAll
possono essere usati solo su List<T>
istanze (o istanze di classi che ereditano da esso, ovviamente).
Inoltre, differiscono nello scopo reale. Where
restituisce un'istanza IEnumerable
che viene eseguita su richiesta quando viene elencato l'oggetto. FindAll
restituisce un nuovo List<T>
che contiene gli elementi richiesti. FindAll
è più come chiamare Where(...).ToList()
un'istanza di IEnumerable
.
La differenza più grande per me è che .FindAll è disponibile anche in .Net 2.0. Non ho sempre il lusso di programmare in .Net 3.5, quindi provo a ricordare i metodi "nativi" delle raccolte generiche .Net.
È successo più volte che ho implementato un metodo List già disponibile perché non riuscivo a LINQ.
Ciò che trovo utile in questo caso è che, usando VS2008, posso usare l'inferenza del tipo e la sintassi lambda. Queste sono funzionalità del compilatore, non funzionalità del framework. Questo significa che posso scrivere questo e rimanere ancora all'interno di .Net 2.0:
var myOddNums = myNums.FindAll(n => n%2==1);
Ma se hai LINQ disponibile, è importante mantenere la differenza tra l'esecuzione differita e l'esecuzione immediata.
Se ricordo bene, la differenza principale (oltre a ciò che sono implementati su: IEnumerable<T>
vs. List<T>
) è che Where
implementa l'esecuzione differita, dove in realtà non esegue la ricerca fino a quando non ne hai bisogno, usandola ad esempio in un ciclo foreach. FindAll
è un metodo di esecuzione immediata.
Ho fatto alcuni test su un elenco di 80.000 oggetti e ho scoperto che Find()
può essere fino al 1000% più veloce rispetto all'uso di un Where
con FirstOrDefault()
. Non lo sapevo fino al test di un timer prima e dopo ogni chiamata. A volte era lo stesso tempo, altre volte era più veloce.