Удаление обработчика xOb.Xhandler.



Событие получено объектом W

Событие получено объектом Y

 

Попытка удалить обработчик xOb.Xhandler еще раз.

Обработчик событий не найден.

Событие получено объектом W

Событие получено объектом Y

 

Добавление обработчика zOb.Zhandler.

Событие получено объектом W

Событие получено объектом X

Событие получено объектом Y

 

Рассмотрим данную программу более подробно. Сначала в ней определяется делегат обработчиков событий MyEventHandler. Затем объявляется класс MyEvent. В самом его начале определяется массив обработчиков событий evnt, состоящий из трех элементов.

 

MyEventHandler[] evnt = new MyEventHandler[3];

 

Этот массив служит для хранения обработчиков событий, добавляемых в цепочку событий. По умолчанию элементы массива evnt инициализируются пустым значением (null).

Далее объявляется событие SomeEvent. В этом объявлении используется приведенная ниже аксессорная форма оператора event.

 

public event MyEventHandler SomeEvent {

Добавить событие в список,

add {

int i;

for(i=0; i < 3; i++)

if(evnt[i] == null) {

evnt[i] = value;

break;

}

if (i == 3) Console.WriteLine("Список событий заполнен.");

}

Удалить событие из списка,

remove {

int i;

for(i=0; i < 3; i++)

if(evnt[i] == value) {

evnt[i] = null;

break;

}

}

}

 

Когда в цепочку событий добавляется обработчик событий, вызывается аксессор add, и в первом неиспользуемом (т.е. пустом) элементе массива evnt запоминается ссылка на этот обработчик, содержащаяся в неявно задаваемом параметре value. Если в массиве отсутствуют свободные элементы, то выдается сообщение об ошибке. (Разумеется, в реальном коде при переполнении списка лучше сгенерировать соответствующее исключение.) Массив evnt состоит всего из трех элементов, поэтому в нем можно сохранить только три обработчика событий. Когда же обработчик событий удаляется из цепочки событий, то вызывается аксессор remove и в массиве evnt осуществляется поиск ссылки на этот обработчик, передаваемой в качестве параметра value. Если ссылка найдена, то соответствующему элементу массива присваивается пустое значение (null), а значит, обработчик удаляется из цепочки событий.

При запуске события вызывается метод OnSomeEvent(). В этом методе происходит циклическое обращение к элементам массива evnt для вызова по очереди каждого обработчика событий.

Как демонстрирует рассматриваемый здесь пример программы, механизм хранения обработчиков событий нетрудно реализовать, если в этом есть потребность. Но для большинства приложений более подходящим оказывается используемый по умолчанию механизм хранения обработчиков событий, который обеспечивает форма оператора event без аксессоров. Тем не менее аксессорная форма оператора event используется в особых случаях. Так, если обработчики событий необходимо выполнять в программе в порядке их приоритетности, а не в том порядке, в каком они вводятся в цепочку событий, то для их хранения можно воспользоваться очередью по приоритету.

------------------------------------

ПРИМЕЧАНИЕ

В многопоточных приложениях обычно приходится синхронизировать доступ к аксессо-рам событий. Подробнее о многопоточном программировании речь пойдет в главе 23.

------------------------------------

 

 

Разнообразные возможности событий

 

События могут быть определены и в интерфейсах. При этом события должны предоставляться классами, реализующими интерфейсы. События могут быть также определены как абстрактные (abstract). В этом случае конкретное событие должно быть реализовано в производном классе. Но аксессорные формы событий не могут быть абстрактными. Кроме того, событие может быть определено как герметичное (sealed). И наконец, событие может быть виртуальным, т.е. его можно переопределить в производном классе.

 

 

Применение анонимных методов и лямбда-выражений вместе с событиями

 

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

Как упоминалось выше, лямбда-выражениям теперь отдается большее предпочтение по сравнению с анонимными методами, поэтому начнем именно с них. Ниже приведен пример программы, в которой лямбда-выражение используется в качестве обработчика событий.

 

// Использовать лямбда-выражение в качестве обработчика событий,

using System;

 

// Объявить тип делегата для события,

delegate void MyEventHandler(int n);

 

// Объявить класс, содержащий событие,

class MyEvent {

public event MyEventHandler SomeEvent;


Дата добавления: 2019-02-12; просмотров: 265; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!