При использовании C# 3.0 (VS2008) затем, LINQ к Объектам может сделать очень похожие вещи:
List<Foo> fooList = new List<Foo>();
IEnumerable<Foo> extract = from foo in fooList where foo.Bar > 10 select Foo.Name.ToUpper();
Matt упомянул выражения запроса. Они доступны для LINQ в целом, между прочим - не только LINQ к Объектам. (Например, тот же запрос относился к LINQ SQL datacontext, выполнит фильтр и проекцию на базе данных.)
выражения запроса в C# 3 являются просто синтаксическим сахаром по написанию нормального кода C# - хотя выражения запроса обычно заканчивают тем, что звонили дополнительные методы . (Они не имеют к, и компилятор не заботится, но они обычно делают.) Существуют различные вещи, которые можно сделать с наборами, которые не доступны в выражениях запроса C#, но которые поддерживаются вызовами метода, таким образом, стоит знать об обоих видах синтаксиса. Например, выражение запроса Matt:
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());
, Если Вы хотите (сказать) фильтр на основе индекса значения в исходном наборе, можно использовать соответствующая перегрузка того, Где , который недоступен через выражения запроса:
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 к Объектам основано на дополнительных методах, можно добавить собственные операторы, которые выглядят "собственными" к LINQ - хотя Вы не можете изменить синтаксис выражения запроса сами.)
List
ведет себя так же, как составление списков, выполняя одну и ту же операцию над каждым элементом существующего списка и затем возвращая новую коллекцию. Это альтернатива использованию Linq, особенно если вы все еще используете .NET 2.0.
В Python, простой пример понимания списка:
>>> foo = [1, 2, 3]
>>> bar = [x * 2 for x in foo]
>>> bar
[2, 4, 6]
Для C # 3.0 вы можете передать лямбда-функцию, определяющую, какой тип функции отображения требуется.
public static void Main()
{
var foo = new List<int>{ 1, 2, 3};
var bar = foo.ConvertAll(x => x * 2); // list comprehension
foreach (var x in bar)
{
Console.WriteLine(x); // should print 2 4 6
}
}
Для C # 2.0 вы можете использовать анонимный метод с делегатом Converter
для выполнения эквивалента.
public static void Main()
{
List<int> foo = new List<int>(new int[]{ 1, 2, 3});
List<int> bar = foo.ConvertAll(new Converter<int, int>(delegate(int x){ return x * 2; })); // list comprehension
foreach (int x in bar)
{
Console.WriteLine(x); // should print 2 4 6
}
}
(Примечание: то же самое можно сделать с массивами, используя Array.ConvertAll