День сто тридцать девятый. #ЗаметкиНаПолях

Лямбда-выражения. Окончание

Вывод типа в лямбда-выражениях

При написании лямбда-выражений часто нет необходимости указывать тип для входных параметров, поскольку компилятор может вывести тип на основе тела лямбда выражения, типов параметров и других факторов, описанных в спецификации языка C#. Для большинства стандартных операторов запросов первым вводом является тип элементов в исходной последовательности. Если вы запрашиваете IEnumerable<Customer>, то входная переменная приводится к объекту Customer, что означает, что у вас есть доступ к её методам и свойствам:

customers.Where(c => c.City == "London");

Общие правила для вывода типа:

- Лямбда должна содержать то же количество параметров, что и тип делегата.

- Каждый входной параметр в лямбда-выражении должен быть неявно преобразован в соответствующий ему параметр делегата.

- Возвращаемое значение лямбды (если оно есть) должно быть неявно конвертируемым в возвращаемый тип делегата.

Замечание: лямбда-выражения сами по себе не имеют типа, потому что общая система типов не имеет внутреннего понятия «лямбда-выражение». Однако иногда удобно неформально говорить о «типе» лямбда-выражения. В этих случаях тип относится к типу делегата или типу выражения, в которые преобразуется лямбда-выражение.



Область видимости переменных в лямбда-выражениях

Лямбда-выражение может ссылаться на внешние переменные (см. пост про анонимные методы https://t.me/NetDeveloperDiary/163), которые находятся внутри метода, определяющего лямбда-выражение, или в типе, содержащем лямбда-выражение. Переменные, захваченные таким образом, сохраняются для использования в лямбда-выражении, даже они иначе вышли бы из области видимости и подлежали бы сборке мусора.

Правила области видимости в лямбда-выражениях:

- Внешняя переменная должна быть явно определена, прежде чем она сможет быть использована в лямбда-выражении.

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

- Переменные, введенные в лямбда-выражении, не видны во включающем выражение методе.

- Лямбда-выражение не может напрямую захватить параметр in, ref или out из включающего его метода.

- Оператор return в лямбда-выражении не приводит к возврату включающего его метода.

- Лямбда-выражение не может содержать оператор goto, break или continue, если цель этого оператора находится вне блока лямбда-выражения, и наоборот.



Источник: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions