Тема 23. Делегаты, события и лямбда-выражения
Делегаты
Делегат - это тип, который представляет собой ссылки на методы с определенным списком параметров и возвращаемым типом. При создании экземпляра делегата этот экземпляр можно связать с любым методом с совместимой сигнатурой и возвращаемым типом.Метод можно вызвать (активировать) с помощью экземпляра делегата.
Делегаты используются для передачи методов в качестве аргументов к другим методам. В следующем примере показано объявление делегата:
public delegate int PerformCalculation(int x, int y);
Благодаря возможности ссылаться на метод как на параметр, делегаты оптимально подходят для задания функций обратного вызова. Например, ссылка на метод, сравнивающий два объекта, может быть передана в качестве аргумента алгоритму сортировки. Поскольку код сравнения находится в отдельной процедуре, алгоритм сортировки может быть написан в более обобщенном виде.
События
События позволяют классу или объекту уведомлять другие классы или объекты о возникновении каких-либо ситуаций.Класс, отправляющий (или вызывающий) событие, называется издателем, а классы, принимающие (или обрабатывающие) событие, называются подписчиками.
В C# в стандартном приложении Windows Forms или веб-приложении пользователь подписывается на события, вызываемые элементами управления, такими как кнопки и поля со списками.
События это особый тип многоадресных делегатов, которые можно вызвать только из класса или структуры, в которой они объявлены (класс издателя).Если на событие подписаны другие классы или структуры, их методы обработчиков событий будут вызваны когда класс издателя инициирует событие.
В то время как делегат - это тип, событие - метод класса или структуры типа делегат.
События имеют следующие свойства:
- Издатель определяет момент вызова события, подписчики определяют предпринятое ответное действие.;
- У события может быть несколько подписчиков.Подписчик может обрабатывать несколько событий от нескольких издателей.;
- События, не имеющие подписчиков, никогда не возникают.;
- Обычно события используются для оповещения о действиях пользователя, таких как нажатия кнопок или выбор меню и их пунктов в графическом пользовательском интерфейсе.;
- Если событие имеет несколько подписчиков, то при его возникновении происходит синхронный вызов обработчиков событий.Сведения об асинхронном вызове событий см. в разделе Calling Synchronous Methods Asynchronously.;
- В библиотеке классов .NET Framework в основе событий лежит делегат EventHandler и базовый класс EventArgs.
Лямбда-выражения
В C# версии 2.0 введена концепция анонимных методов, которые позволяют передавать блоки кода в виде параметров вместо использования отдельно определенного метода.В C# 3.0 для краткой записи встроенных блоков кода введены лямбда-выражения.В результате компиляции как анонимных методов, так и лямбда-выражений (в определенном контексте) получаются типы делегатов.В настоящее время эти возможности называются анонимными функциями.
Выражения-лямбды возвращают результат выражения и имеют следующую основную форму:
(input parameters) => expression
Если лямбда имеет только один входной параметр, скобки можно не ставить, во всех остальных случаях они обязательны. Если входных параметров два и более, то они разделяются запятыми и заключаются в скобки:
(x, y) => x == y
Иногда компилятору бывает трудно или даже невозможно вывести типы входных параметров. В этом случае типы можно указать в явном виде, как показано в следующем примере:
(int x, string s) => s.Length > x
Пример:
delegate int tdel(int i);
static void Main(string[] args)
{
tdel myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
Дополнительная литература
[Делегаты (Руководство по программированию на C#)] (https://msdn.microsoft.com/ru-ru/library/ms173171.aspx)
Делегаты и события в .NET http://habrahabr.ru/post/198694/
event (Справочник по C#) https://msdn.microsoft.com/ru-ru/library/8627sbea.aspx
События (Руководство по программированию в C#) https://msdn.microsoft.com/ru-ru/library/awbftdfh.aspx Лямбда-выражения (Руководство по программированию в C#) https://msdn.microsoft.com/ru-ru/library/bb397687.aspx