as
определенно не очень хороший подход, и я был бы удивлен, если бы он работал.
С точки зрения того, что является "лучшим", я бы предложил foreach
вместо ForEach
:
foreach(var item in myList.Where(p=>p.Length>5)) {
... // do something with item
}
Если вы отчаянно хотите использовать методы списка, возможно:
myList.FindAll(p=>p.Length>5).ForEach(...);
или действительно
var result = myList.FindAll(p=>p.Length>5).BinarySearch(...);
, но учтите, чтодля этого (в отличие от первого) требуется дополнительная копия данных, что может быть затруднительно, если в myList
100 000 элементов длиной более 5.
Причина, по которой LINQвозвращает IEnumerable<T>
в том смысле, что этот объект (LINQ-to-Objects) предназначен для компоновки и потоковой передачи, что не возможно при переходе к списку.Например, комбинация из нескольких where
/ select
и т. Д. Должна , а не строго создавать много промежуточных списков (и, действительно, LINQ этого не делает).
Этоеще более важно, если учесть, что не все последовательности ограничены;есть бесконечные последовательности, например:
static IEnumerable<int> GetForever() {
while(true) yield return 42;
}
var thisWorks = GetForever().Take(10).ToList();
как до ToList
это составные итераторы, не генерация промежуточногосписок.Однако есть несколько буферизованных операций, таких как OrderBy
, которые должны сначала прочитать все данные.Большинство операций LINQ являются потоковыми.