События и делегаты

Событие представляет собой сообщение, посылаемое объектом, чтобы сигнализировать о совершении какого-либо действия. Это действие может быть вызвано в результате взаимодействия с пользователем, например при нажатии кнопки мыши, или может быть обусловлено логикой работы программы. Объект, вызывающий событие, называется отправителем события. Объект, который захватывает событие и реагирует на него, называется получателем события.

При обмене событиями классу отправителя событий не известен объект или метод, который будет получать (обрабатывать) сформированные отправителем события. Необходимо, чтобы между источником и получателем события имелся посредник (или механизм подобный указателю). .NET Framework определяет специальный тип (Delegate), обеспечивающий функциональные возможности указателя функции.

Делегат является классом, который может хранить ссылку на метод. В отличие от других классов класс делегата имеет сигнатуру и может хранить ссылки только на методы, соответствующие этой сигнатуре. Таким образом, делегат эквивалентен типобезопасному указателю функции или обратному вызову. Хотя делегаты имеют и другие направления использования, здесь будут рассматриваться только функциональные возможности делегатов по обработке событий. Объявление делегата является достаточным для определения класса делегата. Объявление предоставляет сигнатуру делегата, а среда CLR обеспечивает реализацию. В следующем примере показан порядок объявления делегата событий.

Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
public delegate void AlarmEventHandler(Object^ sender, AlarmEventArgs^ e);

Синтаксис сходен с синтаксисом объявления метода. Однако зарезервированное слово delegate сообщает компилятору, что AlarmEventHandler является типом делегата. По соглашению делегаты событий в .NET Framework имеют два параметра: источник, вызвавший событие, и данные для события.

Экземпляр делегата AlarmEventHandler можно привязать к любому методу, который соответствует его сигнатуре, такому как метод AlarmRang класса WakeMeUp, как показано в следующем примере.

Public Class WakeMeUp
    ' AlarmRang has the same signature as AlarmEventHandler.
    Public Sub AlarmRang(sender As Object, e As AlarmEventArgs)
        '...
    End Sub
    '...
End Class
public class WakeMeUp
{
    // AlarmRang has the same signature as AlarmEventHandler.
    public void AlarmRang(object sender, AlarmEventArgs e)
    {
        //...
    }
    //...
}
public ref class WakeMeUp
{
public:
    // AlarmRang has the same signature as AlarmEventHandler.
    void AlarmRang(Object^ sender, AlarmEventArgs^ e)
    {
        //...
    }
    //...
};

Пользовательские делегаты событий необходимы только в случаях, когда событие создает данные для события. Многие события, включая некоторые события пользовательского интерфейса, например щелчки мышью, не создают данных для события. В таких ситуациях делегат события, предоставляемый библиотекой классов для события без данных, System.EventHandler является целесообразным. Его объявление приводится ниже.

Delegate Sub EventHandler(sender As Object, e As EventArgs)
delegate void EventHandler(object sender, EventArgs e);
delegate void EventtHandler(Object^ sender, EventArgs^ e);

Делегаты событий являются многоадресными. Это означает, что они могут хранить ссылки на несколько методов обработки событий. Дополнительные сведения см. в разделе Delegate. Делегаты позволяют осуществлять гибкий и детальный контроль при обработке событий. Делегат действует как диспетчер событий для класса, вызвавшего событие, обслуживая для события список зарегистрированных обработчиков событий.

Сведения об использовании делегатов для предоставления функциональных возможностей событий в компоненте или элементе управления содержатся в разделе Создание событий.

Общие сведения о потреблении событий в приложениях содержатся в разделе Потребление событий.

См. также

Задачи

Практическое руководство. Вызов и прием событий

Практическое руководство. Соединение методов обработчика событий с событиями

Основные понятия

Прием событий

Вызов события

Другие ресурсы

Обработка и вызов событий