Ключевое слово delegate
используется не только при определении типа делегата, но и для объявления анонимных методов. Анонимный метод в C# — это метод, который не имеет имени. Такие методы могут преобразоваться в тип делегата
Применение анонимных методов
Анонимные методы не могут существовать сами по себе, например, размещаться в классе и, затем, вызываться по мере надобности так как мы просто не сможем такой метод вызвать — у него нет имени. Такие методы создаются с конкретной целью — быть преобразованными в тип делегата. Описание анонимного метода выглядит следующим образом:
delegate(список_параметров) { код метода }
Например, рассмотрим такой делегат:
delegate void EventHandler();
В предыдущей части, чтобы определить для такого делегата метод мы создавали новый метод и, затем, назначали этот метод делегату. Используя анонимный метод, мы могли бы написать следующий код:
EventHandler writeAbout = delegate() { Console.WriteLine("Это анонимный метод!"); };
Если какой-либо метод требует в качестве параметра делегат, то мы также можем воспользоваться анонимными методами:
double summa = Calculate(10, 20, delegate (double a, double b) { return a + b; }); Console.WriteLine($"Сумма двух чисел {summa}"); double mult = Calculate(10, 20, delegate (double a, double b) { return a * b; }); Console.WriteLine($"Произведение двух чисел {mult}"); double Calculate(double a, double b, Operation operation) { return (double)operation?.Invoke(a, b); } delegate double Operation(double x, double y);
В этом примере мы объявили тип делегата:
delegate double Operation(double x, double y);
а также метод, который требуется в качестве параметра делегат:
double Calculate(double a, double b, Operation operation) { return (double)operation?.Invoke(a, b); }
но при вызове этого метода мы передавали в качестве параметров анонимные методы. Первый анонимный метод складывал два числа:
double summa = Calculate(10, 20, delegate (double a, double b) { return a + b; });
а второй — вычислял произведение:
double mult = Calculate(10, 20, delegate (double a, double b) { return a * b; });
Результат работы программы будет следующим:
Произведение двух чисел 200
Особенности применения анонимных методов
Если анонимный метод использует параметры, то они должны соответствовать параметрам делегата. Например, здесь
EventHandler handler = delegate(string text, ConsoleColor color) { Console.ForegroundColor = color; Console.WriteLine(text); }; delegate void EventHandler(string text);
мы получим ошибку:
Действительно, наш делегат принимает всего один параметр, а анонимный метод использует два параметра. В принципе, это вполне логично и понятно. Однако, особенностью анонимного метода является то, что, если анонимный метод не содержит никаких параметров, то он соответствует любому делегату. Проверить это достаточно просто:
Operation operation = delegate { Console.WriteLine("А этот анонимный метод не содержит параметров и соответствует любому делегату"); return 0; }; delegate double Operation(double x, double y);
Для делегата Operation
мы определили анонимный метод без параметров, хотя сам делегат требует наличие двух параметров — чисел. Однако такой код вполне успешно скомпилируется и выполнится. Здесь стоит обратить внимание также на запись анонимного метода — так как у него отсутствуют параметры, то круглые скобки мы опускаем и сразу записываем тело метода.
Еще один момент, связанный с анонимными методами заключается в том, что анонимный метод имеет доступ ко всем переменным, определенным во внешнем коде. Например,
double x = 5; double y = 6; Operation operation = delegate { Console.WriteLine("А этот анонимный метод не содержит параметров и соответствует любому делегату"); return x + y; }; Console.WriteLine($"{operation(200,200)}");
переменные x и y определены во внешнем коде, однако, анонимный метод, используемый для делегата Operation их «видит» и может использовать. Поэтому в консоли мы увидим следующий вывод:
11
Итого
Анонимный метод — это метод, не имеющий имени. Такие методы не могут существовать сами по себе, однако могут преобразовываться в тип делегата. Анонимный метод без параметров соответствует любому типы делегата, в то время как, анонимный метод с параметрами должен полностью соответствовать типу делегата.