LINQ, где () против FindAll ()


125

Может кто-нибудь объяснить, чем отличаются функции LINQ Where (..) и FindAll (..)? Кажется, они оба делают одно и то же ...



Ответы:


203

FindAll()- это функция List<T>типа, а не метод расширения LINQ, например Where. Методы расширения LINQ работают с любым типом, который реализует IEnumerable, тогда как FindAllмогут использоваться только с List<T>экземплярами (или, конечно, с экземплярами классов, которые наследуются от него).

Кроме того, они различаются по собственному назначению. Whereвозвращает экземпляр, IEnumerableкоторый выполняется по запросу при перечислении объекта. FindAllвозвращает новый List<T>, содержащий запрошенные элементы. FindAllбольше похоже на вызов Where(...).ToList()экземпляра IEnumerable.


20
Да, где ленивая версия findall
Пьерретен

2
code.msdn.microsoft.com/LINQ-Query-Execution-ce0d3b95 объясняет разницу между ленивым (отложенным) и немедленным выполнением. По сути, в некоторых случаях вам не нужен весь список, вы можете перебирать элементы, пока что-то не произойдет, а затем остановиться. Здесь пригодится ленивость, но в зависимости от реализации может привести к непредсказуемым результатам (все объяснено в ссылке). Надеюсь это поможет.
nurchi 06

10

Самая большая разница для меня в том, что .FindAll также доступен в .Net 2.0. У меня не всегда есть возможность программировать в .Net 3.5, поэтому я стараюсь помнить «родные» методы общих коллекций .Net.

Несколько раз случалось, что я сам реализовывал уже доступный метод List, потому что не мог LINQ.

В этом случае я считаю удобным то, что, используя VS2008, я могу использовать вывод типа и лямбда-синтаксис. Это функции компилятора, а не фреймворка. Это означает, что я могу написать это и по-прежнему оставаться в рамках .Net 2.0:

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

Но если у вас есть доступный LINQ, важно сохранять разницу между отложенным выполнением и немедленным выполнением.


6

Если я правильно помню, основное различие (помимо того, в чем они реализованы: IEnumerable<T>vs. List<T>) заключается в том, что Whereреализуется отложенное выполнение, где он фактически не выполняет поиск, пока он вам не понадобится - например, используя его в цикле foreach. FindAllэто метод немедленного исполнения.


3

Я провел несколько тестов со списком из 80K объектов и обнаружил, что это Find()может быть на 1000% быстрее, чем при использовании Whereс FirstOrDefault(). Я не знал этого, пока не тестировал таймер до и после каждого звонка. Иногда было в одно и то же время, иногда быстрее.


5
Вы тоже пробовали получить доступ к коллекции? Enumerable.Where () использует отложенное выполнение и не оценивается до обращения к коллекции, что может привести к ложным представлениям о том, действительно ли она быстрее или нет. Тем не менее, по большей части, как правило, быстрее использовать перечисляемые объекты, а не статические коллекции (например, Type <T> и Array <T>).
Себастьян Джоб Бьёрнагер Йенсен

Вопрос по поводу FindAll. Очевидно, что Find будет быстрее, чем Where (принимая все значения) и получит FirstOrDefault
Vivek MVK
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.