Мэтт упомянул выражения запроса. Кстати, они доступны для LINQ вообще, а не только для LINQ to Objects. (Например, тот же запрос, примененный к текстовому тексту LINQ to SQL, будет выполнять фильтрацию и проекцию базы данных.)
Выражения запроса в C # 3 являются просто синтаксическим сахаром над написанием нормального кода C # - хотя выражения запроса обычно заканчиваются вызовом методов расширения . (Они не обязаны это делать, и компилятору это не важно, но обычно это так.) Существуют различные вещи, которые вы можете делать с коллекциями, которые недоступны в выражениях запросов C #, но которые поддерживаются вызовами методов, поэтому Стоит знать о обоих видах синтаксиса. Например, выражение запроса Мэтта:
List<Foo> fooList = new List<Foo>();
IEnumerable<string> extract = from foo in fooList where foo.Bar > 10 select foo.Name.ToUpper();
"предварительно обработан" в:
List<Foo> fooList = new List<Foo>();
IEnumerable<string> extract = fooList.Where(foo => foo.Bar > 10)
.Select(foo => foo.Name.ToUpper());
Если вы хотите (скажем) фильтровать на основе индекса значения в исходной коллекции, вы можете использовать соответствующую перегрузку Where , которая недоступна через выражения запроса:
List<Foo> fooList = new List<Foo>();
IEnumerable<string> extract = fooList.Where((foo, index) => foo.Bar > 10 + index)
.Select(foo => foo.Name.ToUpper());
Или вы можете найти длину самого длинного имени, соответствующего критериям:
List<Foo> fooList = new List<Foo>();
int longestName = fooList.Where((foo, index) => foo.Bar > 10 + index)
.Select(foo => foo.Name)
.Max();
(У вас нет для проецирования и макс в отдельных методах - есть перегрузка Max
, которая также принимает проекцию.)
Я хочу сказать, что используя методы расширения, вы можете очень легко создавать сложные запросы.
Вы упоминаете также генераторы Python - в C # это имеет вид блоков итераторов . Действительно, они невероятно полезны при реализации LINQ-подобных операторов. (Поскольку большая часть LINQ to Objects основана на методах расширения, вы можете добавить свои собственные операторы, которые выглядят «родными» для LINQ - хотя вы не можете изменить синтаксис выражения запроса самостоятельно.)