Delegate void MyEventHandler();

// Объявить класс для хранения максимум трех событий, class MyEvent {

MyEventHandler[] evnt = new MyEventHandler[3];

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;

}

if (i == 3) Console.WriteLine("Обработчик событий не найден.");

}

}

// Этот .метод вызывается для запуска событий, public void OnSomeEvent() {

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

if(evnt[i] != null) evnt[i]();

}

}

// Создать ряд классов, использующих делегат MyEventHandler. class W {

public void Whandler() {

Console.WriteLine("Событие получено объектом W");

}

}

class X {

public void Xhandler() {

Console.WriteLine("Событие получено объектом X");

}

}

class Y {

public void Yhandler() {

Console.WriteLine("Событие получено объектом Y");

class Z {

public void Zhandler() {

Console.WriteLine("Событие получено объектом Z");

}

}

class EventDemo5 { static void Main() {

MyEvent evt = new MyEvent();

// Добавить обработчики в цепочку событий.

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), а значит, обработчик удаляется из цепочки событий.

Наши рекомендации