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 FindAllmogą 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. Wherezwraca instancję, IEnumerablektóra jest wykonywana na żądanie, gdy obiekt jest wyliczany. FindAllzwraca nowy, List<T>który zawiera żądane elementy. FindAlljest bardziej jak wywołanie Where(...).ToList()wystąpienia IEnumerable.
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 wyjaśnia różnice między opóźnionym (odroczonym) a natychmiastowym wykonaniem. Zasadniczo w niektórych przypadkach nie potrzebujesz całej listy, możesz chcieć przejrzeć elementy, aż coś się stanie, a następnie zatrzymać. Tutaj przydaje się lenistwo, ale w zależności od implementacji może prowadzić do nieprzewidywalnych rezultatów (wszystko wyjaśniono w linku). Mam nadzieję że to pomoże.
nurchi
10
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 Whereimplementuje 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. FindAlljest 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 Wherez 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.
Czy też próbowałeś uzyskać dostęp do kolekcji? Enumerable.Where () używa odroczonego wykonania i nie jest oceniane przed uzyskaniem dostępu do kolekcji, co może prowadzić do fałszywych koncepcji dotyczących tego, czy faktycznie jest ona szybsza, czy nie. Mimo to w przeważającej części zwykle szybciej używa się wyliczalnych niż statycznych kolekcji (takich jak Type <T> i Array <T>).
Sebastian Job Bjørnager Jensen
Pytanie dotyczy FindAll. Jest oczywiste, że Find będzie szybszy niż Where (biorąc wszystkie wartości) i otrzymanie FirstOrDefault
Odpowiedzi:
FindAll()
jest funkcjąList<T>
typu, nie jest to metoda rozszerzenia LINQ, taka jakWhere
. Metody rozszerzenia LINQ działają na każdym typie, który implementujeIEnumerable
, natomiastFindAll
mogą być używane tylko wList<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łanieWhere(...).ToList()
wystąpieniaIEnumerable
.źródło
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:
Ale jeśli masz dostępne LINQ, ważne jest zachowanie różnicy między odroczonym wykonaniem a natychmiastowym wykonaniem.
źródło
Jeśli dobrze pamiętam, główna różnica (poza tym, co są zaimplementowane w:
IEnumerable<T>
vs.List<T>
) polega na tym, żeWhere
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.źródło
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życieWhere
zFirstOrDefault()
. 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.źródło