C# имеет что-нибудь сопоставимым с пониманиями списка Python?

19
задан Sнаđошƒаӽ 27 February 2017 в 14:00
поделиться

3 ответа

При использовании 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();
22
ответ дан 30 November 2019 в 03:03
поделиться

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 - хотя Вы не можете изменить синтаксис выражения запроса сами.)

15
ответ дан 30 November 2019 в 03:03
поделиться

List .ConvertAll ведет себя так же, как составление списков, выполняя одну и ту же операцию над каждым элементом существующего списка и затем возвращая новую коллекцию. Это альтернатива использованию 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

5
ответ дан 30 November 2019 в 03:03
поделиться