LINQ, Where () vs FindAll ()

Antworten:

202

FindAll()ist eine Funktion für den List<T>Typ, es ist keine LINQ-Erweiterungsmethode wie Where. Die LINQ-Erweiterungsmethoden funktionieren für jeden Typ, der implementiert wird IEnumerable, während FindAllsie nur für List<T>Instanzen (oder natürlich für Instanzen von Klassen, die davon erben) verwendet werden können.

Darüber hinaus unterscheiden sie sich im tatsächlichen Zweck. WhereGibt eine Instanz zurück IEnumerable, die bei Bedarf ausgeführt wird, wenn das Objekt aufgelistet wird. FindAllGibt eine neue zurück List<T>, die die angeforderten Elemente enthält. FindAllist eher wie das Aufrufen Where(...).ToList()einer Instanz von IEnumerable.

Adam Robinson
quelle
20
Ja, wo ist eine faule Version von findall
Pierreten
2
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 erklärt die Unterschiede zwischen verzögerter (verzögerter) und sofortiger Ausführung. Grundsätzlich benötigen Sie in einigen Fällen nicht die gesamte Liste. Möglicherweise möchten Sie die Elemente durchlaufen, bis etwas passiert, und dann anhalten. Hier bietet sich Lazy an, kann aber je nach Implementierung zu unvorhersehbaren Ergebnissen führen (alles im Link erklärt). Hoffe das hilft.
Nurchi
10

Der größte Unterschied für mich ist, dass .FindAll auch in .Net 2.0 verfügbar ist. Ich habe nicht immer den Luxus, in .Net 3.5 zu programmieren, daher versuche ich, mich an die "nativen" Methoden der generischen .Net-Sammlungen zu erinnern.

Es kam mehrmals vor, dass ich selbst eine bereits verfügbare List-Methode implementiert habe, weil ich sie nicht LINQ konnte.

Was ich in diesem Fall praktisch finde , ist , dass mit VS2008, ich kann Typinferenz und die Lambda - Syntax verwenden. Dies sind Compiler-Funktionen, keine Framework-Funktionen. Dies bedeutet, dass ich dies schreiben und trotzdem in .Net 2.0 bleiben kann:

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

Wenn Sie jedoch über LINQ verfügen, ist es wichtig, den Unterschied zwischen verzögerter Ausführung und sofortiger Ausführung beizubehalten.

cfern
quelle
6

Wenn ich mich richtig erinnere, besteht der Hauptunterschied (abgesehen von dem, worauf sie implementiert sind: IEnumerable<T>vs. List<T>) darin, dass Whereeine verzögerte Ausführung implementiert wird, bei der die Suche erst dann durchgeführt wird, wenn Sie sie benötigen - beispielsweise in einer foreach-Schleife. FindAllist eine sofortige Ausführungsmethode.

WayneC
quelle
3

Ich habe einige Tests mit einer Liste von 80K-Objekten durchgeführt und festgestellt, dass Find()diese bis zu 1000% schneller sein können als die Verwendung eines Wherewith FirstOrDefault(). Das wusste ich erst, als ich vor und nach jedem Anruf einen Timer testete. Manchmal war es die gleiche Zeit, manchmal war es schneller.

digiben
quelle
5
Haben Sie auch versucht, auf die Sammlung zuzugreifen? Enumerable.Where () verwendet die verzögerte Ausführung und wird nicht ausgewertet, bevor auf die Sammlung zugegriffen wird. Dies kann zu falschen Vorstellungen darüber führen, ob sie tatsächlich schneller ist oder nicht. Dennoch ist es in der Regel schneller, Enumerables anstelle statischer Sammlungen (wie Typ <T> und Array <T>) zu verwenden.
Sebastian Job Bjørnager Jensen
Die Frage bezieht sich auf FindAll. Es ist offensichtlich, dass Find schneller sein wird als Where (alle Werte annehmen) und FirstOrDefault
Vivek MVK