LINQ, Where () vs FindAll ()


Risposte:


203

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 FindAllpossono essere usati solo su List<T>istanze (o istanze di classi che ereditano da esso, ovviamente).

Inoltre, differiscono nello scopo reale. Whererestituisce un'istanza IEnumerableche viene eseguita su richiesta quando viene elencato l'oggetto. FindAllrestituisce un nuovo List<T>che contiene gli elementi richiesti. FindAllè più come chiamare Where(...).ToList()un'istanza di IEnumerable.


20
Sì, Where is a lazy version of findall
Pierreten,

2
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 spiega le differenze tra esecuzione pigra (differita) ed esecuzione immediata. Fondamentalmente, in alcuni casi, non è necessario l'intero elenco, potresti voler scorrere gli elementi fino a quando non accade qualcosa, quindi fermarti. Qui è dove pigro è utile, ma a seconda dell'implementazione, può portare a risultati imprevedibili (tutto spiegato nel link). Spero che questo ti aiuti.
Nurchi,

10

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.


6

Se ricordo bene, la differenza principale (oltre a ciò che sono implementati su: IEnumerable<T>vs. List<T>) è che Whereimplementa 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.


3

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 Wherecon 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.


5
Hai provato ad accedere anche alla collezione? Enumerable.Where () utilizza l'esecuzione differita e non viene valutata prima dell'accesso alla raccolta, il che potrebbe portare a false concezioni sul fatto che sia effettivamente più veloce o meno. Tuttavia, è per la maggior parte, in genere più veloce utilizzare enumerabili anziché raccolte statiche (come Tipo <T> e Array <T>).
Sebastian Job Bjørnager Jensen,

La domanda riguarda FindAll. È ovvio che Find sarà più veloce di Where (prendendo tutti i valori) e ottenendo il FirstOrDefault
Vivek MVK il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.