Анонимная функция - это особый вид функций, которая объявляется в месте использования и не получает уникального идентификатора для доступа к себе.
При создании анонимные функции либо вызываются напрямую, либо присваивается именованному делегату (Подробнее о делегатах: Делегаты | Delegates). Также вызов конструктора при присваивании делегату функции можно опустить. Анонимную функцию также можно подставить вместо типа именованного делегата в качестве параметра метода.
Если анонимная функция ссылается на переменные, не содержащиеся в её теле (захват), то такая функция называется замыканием.
Существует 3 вида анонимных функций:
Особенность анонимного метода в том, что он требует ключевое слово delegate
, наличие операторных скобок { }
, и может содержать несколько действий\операторов ;
:
myDelegate = delegate { Console.WriteLine("Hello 1"); Console.WriteLine("Hello 2"); };
Вариант с возвращаемым параметром и аргументами:
MyDelegate myDelegate = delegate(int a, int b) { return (a + b); };
Лямбда-Оператор подразумевает использование оператора =>
, который позволяет избавиться от ключевого слова delegate
, требует операторные скобки {}
, и может содержать несколько действий\операторов ;
. Также при отсутствии аргументов, перед оператором =>
необходимо ставить пустые скобки ()
:
myDelegate = () => { Console.WriteLine("Hello 2"); };
Оператор
=>
имеет тот же приоритет, что и=
и является право ассоциативным.
Лямбда-выражение позволяет избавиться от всего синтаксического сахара, но при этом в таком выражении может быть только одно действие, оператор ;
, при этом сам оператор можно опустить :
Лямбда-выражение состоящим из одного оператора(;), в котором отброшен весь синтаксический сахар.
MyDelegate myDelegate = (x) => x * 2;
Оператор
=>
имеет тот же приоритет, что и=
и является право ассоциативным.
Следующие правила применимы к области действия переменной в лямбда-выражениях.
ref
или out
из включающего их метода.goto
, оператор break
или оператор continue
, для которых, метка перехода находится вне тела либо в теле содержащейся анонимной функции.=>
, который читается как "переходит в". Левая часть лямбда-оператора определяет параметры ввода (если таковые имеются), а правая часть содержит выражение или блок оператора. Лямбда-выражение x => x * x
читается как "x переходит в x, x раз".Для использования рекурсии в анонимной функции требуется отдельное присвоение ссылки на делегат с сообщенным лямбда оператором, в месте создания переменной, недопустимо сразу создавать лямбда оператор.
MyDelegate my = null; // Требуется обязательно присвоить null.
my = (int i) =>
{
i--;
Console.WriteLine("Begin {0}", i);
if (i > 0)
my(i);
Console.WriteLine("End {0}", i);
};