Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Lambda-выражение в C#?
Lambda-выражение — это анонимная функция, которая позволяет создавать лаконичные и выразительные блоки кода, представляющие вычисления или операции. По сути, это способ определения делегата или дерева выражений (Expression Tree) "на лету", без необходимости объявления отдельного именованного метода.
Основные характеристики и синтаксис
Lambda-выражения появились в C# 3.0 (2007) и стали фундаментальной частью парадигмы LINQ (Language Integrated Query) и функционального программирования в .NET.
Базовый синтаксис:
(parameters) => expression-or-statement-block
Примеры:
// Простейшее лямбда-выражение
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // Вывод: 25
// С несколькими параметрами
Func<int, int, int> add = (a, b) => a + b;
// С явным указанием типов параметров
Func<string, int, string> repeat = (string s, int n) => string.Concat(Enumerable.Repeat(s, n));
// Многострочное лямбда-выражение с телом-блоком
Action<string> printWithLength = text =>
{
int length = text.Length;
Console.WriteLine($"{text} (длина: {length})");
};
Ключевые особенности
-
Анонимность: Lambda-выражения не имеют имени, что делает их идеальными для одноразовых операций.
-
Гибкость параметров:
- Скобки
()можно опустить, если параметр один - Типы параметров могут выводиться компилятором
- Поддерживаются
params,ref,outиinпараметры
- Скобки
-
Замыкания (Closures): Lambda-выражения могут захватывать переменные из окружающего контекста:
int multiplier = 3;
Func<int, int> multiply = x => x * multiplier;
multiplier = 5; // Изменение влияет на лямбду
Console.WriteLine(multiply(2)); // Вывод: 10, а не 6!
Два вида лямбда-выражений
-
Лямбда-выражения как делегаты:
// Компилируется в делегат Func<int, bool> isEven = n => n % 2 == 0; -
Лямбда-выражения как деревья выражений:
// Компилируется в Expression Tree Expression<Func<int, bool>> isEvenExpr = n => n % 2 == 0; // Может анализироваться, преобразовываться и выполняться в разных контекстах // (например, в LINQ to SQL, Entity Framework)
Практическое применение
- LINQ-запросы:
var numbers = new[] { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0);
- События и асинхронные операции:
button.Click += (sender, e) => MessageBox.Show("Кнопка нажата!");
Task.Run(() =>
{
// Асинхронный код
Console.WriteLine("Выполняется в фоне");
});
- Создание делегатов на лету:
List<Person> people = GetPeople();
people.Sort((p1, p2) => p1.Age.CompareTo(p2.Age));
- Функциональное программирование:
// Композиция функций
Func<int, int> doubleIt = x => x * 2;
Func<int, int> addTen = x => x + 10;
Func<int, int> pipeline = x => addTen(doubleIt(x));
Отличия от анонимных методов
Lambda-выражения пришли на смену более verbose анонимным методам C# 2.0:
// Анонимный метод (устаревший стиль)
Func<int, int> oldWay = delegate(int x) { return x * x; };
// Лямбда-выражение (современный стиль)
Func<int, int> newWay = x => x * x;
Производительность и оптимизации
Начиная с C# 9.0 появились статические лямбда-выражения, которые не захватывают переменные из контекста, что позволяет избежать аллокаций:
// Не захватывает контекст, может быть кэшировано
Func<int, int> staticLambda = static x => x * x;
Ограничения и особенности
- Lambda-выражения не могут содержать
goto,breakилиcontinue, которые выходят за пределы выражения - Они не могут быть
asyncбез явного указанияasync:
Func<Task<int>> asyncLambda = async () =>
{
await Task.Delay(1000);
return 42;
};
Заключение
Lambda-выражения кардинально изменили стиль программирования на C#, сделав код более декларативным, читаемым и выразительным. Они являются краеугольным камнем современных .NET-приложений, особенно в сочетании с LINQ, асинхронным программированием и реактивными подходами. Понимание лямбда-выражений, их семантики захвата переменных и различий между делегатами и деревьями выражений критически важно для эффективной разработки на C#.