Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Выберите лямбда-выражение, если вы хотите передать короткую операцию другому методу, и операция наиболее понятна рядом с вызовом, который её использует. Встроенное правило показывает читателям, как выбрать или преобразовать элементы; именованный метод позволяет им понять назначение операции, прежде чем вникнуть в детали.
Tip
В этой статье рассказывается о практических решениях для разработчиков, которые знают методы и коллекции C#. Полный синтаксис и правила см. в справочнике по лямбда-выражениям.
Лямбда-выражение — это неименованная функция, которую вы пишете там, где другому фрагменту кода требуется поведение.
Следующая лямбда принимает сессию и возвращает, имеет ли сессия открытые места:
session => session.Registered < session.Capacity
Оператор => отделяет параметры слева от тела справа. Прочитайте его как «переходит к».
Передача поведения в метод
Многие API .NET принимают делегат, который представляет поведение с определенным списком параметров и типом возвращаемого значения. Лямбда обеспечивает это поведение. Общие сведения о типах делегатов, таких как Func и Action, см. в статье Лямбда-выражения, делегаты и события.
Следующий пример работает с сессиями воркшопа.
WorkshopSession содержит заголовок, длительность, емкость и количество регистраций.
int maximumMinutes = 60;
var shortSessions = sessions
.Where(session => session.DurationMinutes <= maximumMinutes)
.OrderBy(session => session.Title);
foreach (WorkshopSession session in shortSessions)
{
Console.WriteLine(session.Title);
}
Первая лямбда указывает Where, какие сеансы следует сохранить. Второй указывает OrderBy, по какому значению нужно сортировать. Методы получают поведение, не зная подробностей ни одного из двух правил.
Выбор формы параметра
Выберите кратчайшую форму параметра, которая остается ясной:
session => session.DurationMinutes <= 60
Для одного параметра опустите круглые скобки, когда компилятор может определить тип. Используйте пустые скобки при отсутствии параметров:
() => DateTime.Now
Используйте скобки для двух или более параметров:
(left, right) => left + right
Как правило, метод, получающий лямбда-выражение, предоставляет достаточно сведений, чтобы компилятор выводил типы параметров. Пишите явные типы, когда выведению типов нужна помощь или когда типы улучшают ясность:
(WorkshopSession session) => session.Title
Справочник по лямбда-выражениям охватывает модификаторы параметров, атрибуты, значения по умолчанию и другие специализированные формы.
Выберите выражение или тело инструкции
Используйте лямбда-выражение , если одно выражение вычисляет результат:
session => session.Registered < session.Capacity
Используйте lambda-выражение с операторным телом, если операция содержит более одного оператора. Заключите тело в фигурные скобки и включите return , когда лямбда возвращает значение:
var descriptions = sessions.Select(session =>
{
int seatsLeft = session.Capacity - session.Registered;
string availability = seatsLeft > 0 ? $"{seatsLeft} seats left" : "full";
return $"{session.Title}: {availability}";
});
Console.WriteLine(string.Join(Environment.NewLine, descriptions));
Держите лямбда-операторы с телом-инструкцией краткими. Если телу метода или функции требуется несколько шагов или одна и та же логика отображается несколько раз, присвойте поведению описательное имя с локальной функцией или обычным методом.
Захват значений из окружающей области видимости
Лямбда-выражение может использовать переменную, объявленную в окружающем методе. Это использование называется захватом. В первом примере лямбда-фрагмент захватывает maximumMinutes:
int maximumMinutes = 60;
var shortSessions = sessions.Where(
session => session.DurationMinutes <= maximumMinutes);
Захват помогает краткому правилу использовать локальный контекст. Лямбда захватывает саму переменную, а не копию её значения. Если переменная изменяется до выполнения лямбда-выражения, лямбда-выражение увидит текущее значение.
Сделайте необходимый контекст легко определяемым. Если лямбда-выражение не нуждается во внешнем состоянии, добавьте static, чтобы предотвратить случайный захват и сделать эту независимость видимой для читателей:
var openSessions = sessions.Where(
static session => session.Registered < session.Capacity);
Статическая лямбда может использовать свои параметры, объявленные ею значения, константы и статические члены. Нельзя использовать локальные переменные или состояние экземпляра из окружающего кода.
Выберите лямбда-выражение, группу методов или локальную функцию
Несколько способов записи в C# могут предоставлять поведение для параметра делегата:
- Используйте лямбда-выражение для краткого фрагмента логики, который легко читается рядом с местом вызова.
- Используйте группу методов , если существующий метод имеет требуемую сигнатуру и его имя объясняет поведение.
- Используйте локальную функцию, если объемлющий член требует повторно используемой именованной логики, рекурсии или тела, слишком большого для встроенного лямбда-выражения.
- Используйте обычный метод, если такое поведение требуется нескольким элементам.
группа методов — это имя метода без списка аргументов. Компилятор преобразует подходящий метод в требуемый тип делегата:
var openSessions = sessions.Where(HasOpenSeats);
foreach (WorkshopSession session in openSessions)
{
Console.WriteLine($"Open: {session.Title}");
}
static bool HasOpenSeats(WorkshopSession session) =>
session.Registered < session.Capacity;
Where(HasOpenSeats) выражает то же правило, что и Where(session => HasOpenSeats(session)), используя меньше кода. Имя метода сообщает читателям, что тестирует правило; Встроенное сравнение показывает, как оно проверяет это правило. Сохраняйте лямбда-оболочку при добавлении аргумента, объединении операций или когда она делает вызов более понятным.
Подробные сведения о сравнении языков и регионов см. в разделе Локальные функции.