Отправка события вызывающему коду сводится просто к указанию события по имени наряду со всеми обязательными параметрами, как определено ассоциированным делегатом. Чтобы удостовериться в том, что вызывающий код действительно зарегистрировал событие, перед вызовом набора методов делегата событие следует проверить на равенство
null
. Ниже приведена новая версия метода
Accelerate
класса
Car
:
public void Accelerate(int delta)
{
//
Если автомобиль сломан, то инициировать событие Exploded.
был сконфигурирован для отправки двух специальных событий без необходимости в определении специальных функций регистрации или в объявлении переменных-членов, имеющих типы делегатов. Применение нового объекта вы увидите очень скоро, но сначала давайте чуть подробнее рассмотрим архитектуру событий.
"За кулисами" событий
Когда компилятор C# обрабатывает ключевое слово event, он генерирует два скрытых метода, один с префиксом
add_
, а другой с префиксом
remove_
. За префиксом следует имя события С#. Например, событие
Exploded
дает в результате два скрытых метода с именами
add_Exploded
и
remove_Exploded
. Если заглянуть в код CIL метода
add_AboutToBlow
, то можно обнаружить вызов метода
Delegate.Combine
. Взгляните на частичный код CIL:
.method public hidebysig specialname instance void add_AboutToBlow(
class [System.Runtime]System.EventHandler`1<class CarEvents.
CarEventArgs> 'value') cil
managed
{
...
IL_000b: call class [System.Runtime]System.Delegate
Теперь, когда вы понимаете, каким образом строить класс, способный отправлять события C# (и знаете, что события — всего лишь способ сэкономить время на наборе кода), следующий крупный вопрос связан с организацией прослушивания входящих событий на стороне вызывающего кода.
Прослушивание входящих событий
События C# также упрощают действие по регистрации обработчиков событий на стороне вызывающего кода. Вместо того чтобы указывать специальные вспомогательные методы, вызывающий код просто применяет операции
+=
и
– =
напрямую (что приводит к внутренним вызовам методов
add_XXX
или
remove_XXX
). При регистрации события руководствуйтесь показанным ниже шаблоном:
// ИмяОбъекта.ИмяСобытия +=
// new СвязанныйДелегат(функцияДляВызова);
Car.CarEngineHandler d =
new Car.CarEngineHandler(CarExplodedEventHandler);
myCar.Exploded += d;
Отключить от источника событий можно с помощью операции
– =
в соответствии со следующим шаблоном:
// ИмяОбъекта.ИмяСобытия - =
// СвязанныйДелегат(функцияДляВызова);
myCar.Exploded -= d;
Кроме того, с событиями можно использовать синтаксис группового преобразования методов:
Car.CarEngineHandler d = CarExplodedEventHandler;
myCar.Exploded += d;
При наличии таких весьма предсказуемых шаблонов переделайте вызывающий код, применив на этот раз синтаксис регистрации событий С#:
Console.WriteLine("***** Fun with Events *****\n");