Что такое лямбда-выражение в C#?

«Что такое лямбда-выражение в C#?» — вопрос из категории C# Core, который задают на 32% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Синтаксис: (input-parameters) => expression-or-statement-block

1. Использование с делегатами Func<> и Action<>:

// Лямбда, возвращающая значение (соответствует Func<int, int>)
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // 25

// Лямбда без возвращаемого значения (соответствует Action<string>)
Action<string> greet = name => Console.WriteLine($"Привет, {name}!");
greet("Анна");

// Лямбда с несколькими параметрами и телом в фигурных скобках
Func<int, int, int> sum = (a, b) =>
{
    int result = a + b;
    return result;
};

2. Практическое применение в LINQ и обработке коллекций:

var numbers = new List<int> { 1, 2, 3, 4, 5 };

// Фильтрация: где число четное
var evenNumbers = numbers.Where(n => n % 2 == 0); // [2, 4]

// Преобразование: умножить каждый элемент на 10
var multiplied = numbers.Select(x => x * 10); // [10, 20, 30, 40, 50]

// Сортировка: по убыванию
var sorted = numbers.OrderByDescending(n => n); // [5, 4, 3, 2, 1]

3. Захват переменных из внешней области видимости (closure):

int factor = 10;
// Лямбда "запоминает" значение factor на момент своего создания
Func<int, int> multiplier = n => n * factor;

Console.WriteLine(multiplier(3)); // 30
factor = 20; // Изменение factor НЕ влияет на захваченное значение в данном контексте.
Console.WriteLine(multiplier(3)); // 30 (используется захваченное значение 10)
// Важно: поведение может быть сложным с циклами и асинхронным кодом.

Почему это важно? Лямбды делают код более декларативным, читаемым и компактным, особенно при работе с коллекциями (LINQ), асинхронными операциями и обработкой событий.