Czy ktoś może wyjaśnić, czym różnią się funkcje LINQ Where (..) i FindAll (..)? Obaj wydają się robić to samo ...
Czy ktoś może wyjaśnić, czym różnią się funkcje LINQ Where (..) i FindAll (..)? Obaj wydają się robić to samo ...
Odpowiedzi:
FindAll()
jest funkcją List<T>
typu, nie jest to metoda rozszerzenia LINQ, taka jak Where
. Metody rozszerzenia LINQ działają na każdym typie, który implementuje IEnumerable
, natomiast FindAll
mogą być używane tylko w List<T>
wystąpieniach (lub oczywiście w wystąpieniach klas, które dziedziczą po nim).
Dodatkowo różnią się faktycznym przeznaczeniem. Where
zwraca instancję, IEnumerable
która jest wykonywana na żądanie, gdy obiekt jest wyliczany. FindAll
zwraca nowy, List<T>
który zawiera żądane elementy. FindAll
jest bardziej jak wywołanie Where(...).ToList()
wystąpienia IEnumerable
.
Największą różnicą dla mnie jest to, że .FindAll jest również dostępny w .Net 2.0. Nie zawsze mam luksus programowania w .Net 3.5, więc staram się zapamiętać „natywne” metody ogólnych kolekcji .Net.
Kilka razy zdarzyło się, że sam zaimplementowałem już dostępną metodę List, ponieważ nie mogłem jej LINQ.
Co mogę znaleźć przydatne w tym przypadku jest to, że przy użyciu VS2008, I można użyć typu wnioskowania i składni lambda. Są to funkcje kompilatora, a nie funkcje platformy. Oznacza to, że mogę to napisać i nadal pozostać w .Net 2.0:
var myOddNums = myNums.FindAll(n => n%2==1);
Ale jeśli masz dostępne LINQ, ważne jest zachowanie różnicy między odroczonym wykonaniem a natychmiastowym wykonaniem.
Jeśli dobrze pamiętam, główna różnica (poza tym, co są zaimplementowane w: IEnumerable<T>
vs. List<T>
) polega na tym, że Where
implementuje odroczone wykonanie, w którym faktycznie nie wykonuje wyszukiwania, dopóki go nie potrzebujesz - na przykład używając go w pętli foreach. FindAll
jest metodą natychmiastowego wykonania.
Wykonałem kilka testów na liście obiektów 80 tys. I stwierdziłem, że Find()
może to być nawet o 1000% szybsze niż użycie Where
z FirstOrDefault()
. Nie wiedziałem o tym, dopóki nie przetestowałem timera przed i po każdym połączeniu. Czasami był to ten sam czas, innym razem szybciej.