Изучение лямбда-выражений в C# (отрывок из моей книги: Другие темы)

Лямбда-выражения — это мощные и лаконичные функции, представленные в C#, которые позволяют разработчикам писать компактный и выразительный код. Они предоставляют удобный способ определения встроенных функций или делегатов, делая код более читабельным и эффективным. В этой статье мы углубимся в концепцию лямбда-выражений, их синтаксис и варианты практического использования в C#.

Лямбда-выражение — это простая функция, состоящая из одной строки. «Математическая фраза, которая группирует числа, переменные и операторы, чтобы показать значение чего-либо». По сути, это безымянный метод с лаконичным и функциональным синтаксисом, который обычно используется для написания анонимных методов.

Лямбда-выражение можно использовать для создания делегатов или типов деревьев выражений, и оно основано на концепции функционального программирования.

Лямбда-выражение — это анонимная функция, которую можно использовать для создания делегатов или деревьев выражений. Он обеспечивает краткий способ определения функциональности без явного объявления отдельного метода. Лямбда-выражения часто используются в сценариях, когда небольшой фрагмент кода необходимо передать в качестве аргумента методу или использовать в запросах LINQ.

Основной синтаксис лямбда-выражения в C#:

(parameters) => expression

Параметры заключены в круглые скобки и разделены запятыми, как и в обычном определении метода. Стрелка `=›` отделяет список параметров от выражения, составляющего тело лямбда-выражения.

Вот пример лямбда-выражения, которое складывает два числа:

(int x, int y) => x + y

Приведенное выше лямбда-выражение принимает два целочисленных параметра, `x` и `y`, и возвращает их сумму. Обратите внимание, что типы данных параметров указываются явно.

Теперь давайте представим это в перспективе. Если у нас есть класс ManipNumbers и список случайных положительных чисел, и мы хотим получить только набор чисел из нашего существующего списка, который содержит более широкий диапазон, наш код без лямбда-выражений может выглядеть примерно так:

class ManipNumbers
{
    static void main (string[] args)
    {  
        //list with random numbers
        var randomNumbers = new List<int> {13, 24, 4, 2, 7, 8, 0, 1, 37, 3};


        //create the Lists we'll be needing
        var evenNumbers = new List<int> ();
        var oddNumbers = new List<int> ();
        var numbersAbove7 = new List<int> ();


        //we're going to add even and odd numbers to their resp. Lists
        foreach(var number in randomNumbers)
        {
            if(number % 2 == 0)
            {
                evenNumbers.Add(number); // → 24, 4, 2, 8
            }
            else // if(number % 2 != 0)
            {
                oddNumber.Add(number); // → 13, 7, 1, 37, 3
            }
         }
    }
}

Но с помощью лямбда-выражений наш код можно сократить примерно до такого вида:

class ManipNumbers
{
    static void main (string[] args)
    {
      //list with random numbers
      var randomNumbers = new List<int> {13, 24, 4, 2, 7, 8, 0, 0, 1, 37, 3};
      //create the Lists, get the numbers, and add them to their resp. Lists
      var oddNumbers = randomNumbers.Where(n => n % 2 != 0); // → 13, 7, 1, 37, 3
      var evenNumbers = randomNumbers.Where(n => n % 2 == 0); // → 24, 4, 8, 2
      var numbersAbove7 = randomNumbers.Where(n => n > 7); // → 13, 24, 8, 37
    }
}

Мы начали с создания новой переменной с именем oddNumbers для хранения наших нечетных чисел после их получения, затем мы обращаемся к нашему списку randomNumbers и используем встроенный метод `Where`, который фильтрует последовательность значений на основе предиката, предоставляя нашу лямбда Выражение в качестве его параметра. Лямбда-выражение дает искомое число; тот, который при делении на два (с использованием оператора по модулю) всегда будет иметь остаток. Затем мы делаем то же самое для evenNumbers и numbersAbove7, только изменяя наши правила получения чисел, используя лямбда-выражение.

Теперь давайте посмотрим на другой пример.

Представьте, что вы работаете разработчиком C# в моей любимой музыкальной компании Spotify, и каждый день Spotify хочет отображать на главном экране приложения несколько песен Джона Беллиона для своих пользователей, которые слушают его, таких как я, но только для тех, у кого есть глобальный рейтинг 8,5 и выше. И именно вы кодируете метод выбора песен.

С учетом списка и без лямбда-выражений ваш метод может выглядеть так:

var JonBellionSongslist = new List<Song>
{
  //the release date is not accurate
  new Song{name = "Ooh", releaseDate = new DateTime (2016,11,9), rating = 9.0f },
  new Game{name = "Human", releaseDate = new DateTime(2015, 3, 24), rating = 8.5f },
  new Song{name = "Stupid Deep", releaseDate = new DateTime(2020,9,17), rating = 8.0f},
  new Song{name = "Blu", releaseDate = new DateTime(2021,2,2), rating = 8.0},
  new Song{name = "Guillotine", releaseDate= new DateTime(2021,3,4), rating = 9},
  new Song{name = "Kingdom Come", releaseDate = new DateTime(2014,3,30), rating = 8.0},
  new Song{name = "All Time Low", releaseDate = new DateTime(2016,2,20), rating = 8.0},
  new Song{name = "Maybe IDK", releaseDate = new DateTime(2014,3,6), rating = 7.5}
};

//the method that selects the songs
static Song[] JonSongsOver85(IEnumerable<Song> 
{
  var JonSongs = new List<Song>();

  foreach(var song in songs)
  {
    if(song.rating >= 8.5)
    {
      JonSongs.Add(song);
    }
  }
  
  return JonSongs.ToArray();
}

Но с помощью лямбда-выражений мы можем сделать этот метод короче и чище, например:

var JonBellionSongslist = new List<Song>
{
  //the release date is not accurate
  new Song{name = "Ooh", releaseDate = new DateTime (2016,11,9), rating = 9.0f },
  new Game{name = "Human", releaseDate = new DateTime(2015, 3, 24), rating = 8.5f },
  new Song{name = "Stupid Deep", releaseDate = new DateTime(2020,9,17), rating = 8.0f},
  new Song{name = "Blu", releaseDate = new DateTime(2021,2,2), rating = 8.0},
  new Song{name = "Guillotine", releaseDate= new DateTime(2021,3,4), rating = 9},
  new Song{name = "Kingdom Come", releaseDate = new DateTime(2014,3,30), rating = 8.0},
  new Song{name = "All Time Low", releaseDate = new DateTime(2016,2,20), rating = 8.0},
  new Song{name = "Maybe IDK", releaseDate = new DateTime(2014,3,6), rating = 7.5}
};

//the method that selects the songs
static Song[] JonSongsOver85(IEnumerable<Song> songs)
{
  IEnumerable<Song> JonSongs = songs.Where(sn => sn.rating >= 8.5);
  return JonSongs.ToArray();
}

Таким образом, хотя лямбда-выражения внутри делают то же самое, что и традиционные методы, они помогают нам писать более быстрый, более лаконичный, читаемый и пригодный для повторного использования код.

Не забывайте использовать лямбда-выражения разумно, помня о читабельности кода и удобстве сопровождения. Попрактиковавшись, вы сможете использовать мощь лямбда-выражений для написания элегантного и эффективного кода в своих приложениях на C#.

Это отрывок из моей готовящейся книги Другие темы. Руководство по нескольким темам C#, включая события, делегаты, обобщения и т. д., а также некоторые проекты, в которых используются эти концепции. дела.