Еще одним важным средством С#, основывающимся на делегатах, является собы тие. Событие, по существу, представляет собой автоматическое уведомление о том, что произошло некоторое действие. События действуют по следующему принципу: объект, проявляющий интерес к событию, регистрирует обработчик этого события. Когда же событие происходит, вызываются все зарегистрированные обработчики это го события. Обработчики событий обычно представлены делегатами.
События являются членами класса и объявляются с помощью ключевого слова event. Чаще всего для этой цели используется следующая форма: event делегат_события имя_события;
где делегат
Рассмотрим для начала очень простой пример. // Очень простой пример, демонстрирующий событие. using System; // Объявить тип делегата для события. delegate void MyEventHandler; // Объявить класс, содержащий событие. class MyEvent { public event MyEventHandler SomeEvent; // Этот метод вызывается для запуска события. public void OnSomeEvent { if(SomeEvent != null) SomeEvent; } } class EventDemo { // Обработчик события. static void Handler { Console.WriteLine("Произошло событие"); } static void Main { MyEvent evt = new MyEvent; // Добавить метод Handler в список событий. evt.SomeEvent += Handler; // Запустить событие. evt.OnSomeEvent; } }
Вот какой результат получается при выполнении этого кода. Произошло событие
Несмотря на всю свою простоту, данный пример кода содержит все основные эле менты, необходимые для обработки событий. Он начинается с объявления типа деле гата для обработчика событий, как показано ниже. delegate void MyEventHandler;
Все события активизируются с помощью делегатов. Поэтому тип делегата события определяет возвращаемый тип и сигнатуру для события. В данном случае параметры события отсутствуют, но их разрешается указывать.
Далее создается класс события MyEvent. В этом классе объявляется событие SomeEvent в следующей строке кода. public event MyEventHandler SomeEvent;
Обратите внимание на синтаксис этого объявления. Ключевое слово event уведом ляет компилятор о том, что объявляется событие.
Кроме того, в классе MyEvent объявляется метод OnSomeEvent, вызываемый для сигнализации о запуске события. Это означает, что он вызывается, когда происходит событие. В методе OnSomeEvent вызывается обработчик событий с помощью деле гата SomeEvent. if(SomeEvent != null) SomeEvent;
Как видите, обработчик вызывается лишь в том случае, если событие SomeEvent не является пустым. А поскольку интерес к событию должен быть зарегистрирован в дру гих частях программы, чтобы получать уведомления о нем, то метод OnSomeEvent может быть вызван до регистрации любого обработчика события. Но во избежание вызова по пустой ссылке делегат события должен быть проверен, чтобы убедиться в том, что он не является пустым.
В классе EventDemo создается обработчик событий Handler. В данном простом примере обработчик событий просто выводит сообщение, но другие обработчики могут выполнять более содержательные функции. Далее в методе Main создается объект класса события MyEvent, a Handler регистрируется как обработчик этого события, добавляемый в список. MyEvent evt = new MyEvent; // Добавить метод Handler в список событий. evt.SomeEvent += Handler;
Обратите внимание на то, что обработчик добавляется в список с помощью опера тора +=. События поддерживают только операторы += и -=. В данном случае метод Handler является статическим, но в качестве обработчиков событий могут также служить методы экземпляра.
И наконец, событие запускается, как показано ниже. // Запустить событие. evt.OnSomeEvent;
Вызов метода OnSomeEvent приводит к вызову всех событий, зарегистрирован ных обработчиком. В данном случае зарегистрирован только один такой обработчик, но их может быть больше, как поясняется в следующем разделе. Пример групповой адресации события