Когда в цепочку событий добавляется обработчик событий, вызывается аксессорadd,и в первом неиспользуемом (т.е. пустом) элементе массиваevntзапоминается ссылка на этот обработчик, содержащаяся в неявно задаваемом параметреvalue.Если в массиве отсутствуют свободные элементы, то выдается сообщение об ошибке. (Разумеется, в реальном коде при переполнении списка лучше сгенерировать соответствующее исключение.) Массивevntсостоит всего из трех элементов, поэтому в нем можно сохранить только три обработчика событий. Когда же обработчик событий удаляется из цепочки событий, то вызывается аксессорremoveи в массивеevntосуществляется поиск ссылки на этот обработчик, передаваемой в качестве параметраvalue.Если ссылка найдена, то соответствующему элементу массива присваивается пустое значение(null),а значит, обработчик удаляется из цепочки событий.
При запуске события вызывается методOnSomeEvent. В этом методе происходит циклическое обращение к элементам массиваevntдля вызова по очереди каждого обработчика событий.
Как демонстрирует рассматриваемый здесь пример программы, механизм хранения обработчиков событий нетрудно реализовать, если в этом есть потребность. Но для большинства приложений более подходящим оказывается используемый по умолчанию механизм хранения обработчиков событий, который обеспечивает форма оператораeventбез аксессоров. Тем не менее аксессорная форма оператораeventиспользуется в особых случаях. Так, если обработчики событий необходимо выполнять в программе в порядке их приоритетности, а не в том порядке, в каком они вводятся в цепочку событий, то для их хранения можно воспользоваться очередью по приоритету.
ПРИМЕЧАНИЕ
В многопоточных приложениях обычно приходится синхронизировать доступ к аксессо-рам событий. Подробнее о многопоточном программировании речь пойдет в главе’23.
Разнообразные возможности событий
События могут быть определены и в интерфейсах. При этом события должны предоставляться классами, реализующими интерфейсы. События могут быть также определены как абстрактные(abstract).В этом случае конкретное событие должно быть реализовано в производном классе. Но аксессорные формы событий не могут быть абстрактными. Кроме того, событие может быть определено как герметичное(sealed).И наконец, событие может быть виртуальным, т.е. его можно переопределить в производном классе.
Применение анонимных методов и лямбда-выражений вместе с событиями