Console.WriteLine("Добавление событий.");
evt.SomeEvent += wOb.Whandler;
evt.SomeEvent += xOb.Xhandler;
evt.SomeEvent += yOb.Yhandler;
// Сохранить нельзя - список заполнен,
evt.SomeEvent += zOb.Zhandler;
Console.WriteLine();
// Запустить события,
evt.OnSomeEvent();
Console.WriteLine();
// Удалить обработчик.
Console.WriteLine("Удаление обработчика xOb.Xhandler.");
evt.SomeEvent -= xOb.Xhandler;
evt.OnSomeEvent();
Console.WriteLine();
// Попробовать удалить обработчик еще раз.
Console.WriteLine("Попытка удалить обработчик " +
"xOb.Xhandler еще раз.");
evt.SomeEvent -= xOb.Xhandler;
evt.OnSomeEvent();
Console.WriteLine();
//А теперь добавить обработчик Zhandler.
Console.WriteLine("Добавление обработчика zOb.Zhandler.");
evt.SomeEvent += zOb.Zhandler;
evt.OnSomeEvent();
}
}
Ниже приведен результат выполнения этой программы
Добавление событий.
Список событий заполнен.
Событие получено объектом W
Событие получено объектом X
Событие получено объектом Y
Удаление обработчика 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
для вызова по очереди каждого обработчика событий.