Как видите, синтаксис использования анонимного метода в качестве обработчика событий остается таким же, как и для его применения вместе с любым другим типом делегата. Рекомендации по обработке событий в среде .NET Framework
В C# разрешается формировать какие угодно разновидности событий. Но ради со вместимости программных компонентов со средой .NET Framework следует придер живаться рекомендаций, установленных для этой цели корпорацией Microsoft. Эти рекомендации, по существу, сводятся к следующему требованию: у обработчиков со бытий должны быть два параметра. Первый из них — ссылка на объект, формирую щий событие, второй — параметр типа EventArgs, содержащий любую дополнитель ную информацию о событии, которая требуется обработчику. Таким образом, .NET- совместимые обработчики событий должны иметь следующую общую форму. void обработчик(object отправитель, EventArgs е) { // ... }
Как правило, отправитель — это параметр, передаваемый вызывающим кодом с помощью ключевого слова this. А параметр е типа EventArgs содержит дополни тельную информацию о событии и может быть проигнорирован, если он не нужен. Сам класс EventArgs не содержит поля, которые могут быть использованы для передачи дополнительных данных обработчику. Напротив, EventArgs служит в ка честве базового класса, от которого получается производньгй класс, содержащий все необходимые поля. Тем не менее в классе EventArgs имеется одно поле Empty типа static, которое представляет собой объект типа EventArgs без данных. Ниже приведен пример программы, в которой формируется .NET-совместимое событие. // Пример формирования .NET-совместимого события. using System; // Объявить класс, производный от класса EventArgs. class MyEventArgs : EventArgs { public int EventNum; } // Объявить тип делегата для события. delegate void MyEventHandler(object source, MyEventArgs arg); // Объявить класс, содержащий событие. class MyEvent { static int count = 0; public event MyEventHandler SomeEvent; // Этот метод запускает событие SomeEvent. public void OnSomeEvent { MyEventArgs arg = new MyEventArgs; if(SomeEvent != null) { arg.EventNum = count++; SomeEvent(this, arg); } } } class X { public void Handler(object source, MyEventArgs arg) { Console.WriteLine("Событие " + arg.EventNum + " получено объектом класса X."); Console.WriteLine("Источник: " + source); Console.WriteLine; } } class Y { public void Handler(object source, MyEventArgs arg) { Console.WriteLine("Событие " + arg.EventNum + " получено объектом класса Y."); Console.WriteLine("Источник: " + source); Console.WriteLine; } } class EventDemo6 { static void Main { X ob1 = new X; Y ob2 = new Y; MyEvent evt = new MyEvent; // Добавить обработчик Handler в цепочку событий. evt.SomeEvent += ob1.Handler; evt.SomeEvent += ob2.Handler; // Запустить событие. evt.OnSomeEvent; evt.OnSomeEvent; } }
Ниже приведен результат выполнения этой программы. Событие 0 получено объектом класса X Источник: MyEvent Событие 0 получено объектом класса Y Источник: MyEvent Событие 1 получено объектом класса X Источник: MyEvent Событие 1 получено объектом класса Y Источник: MyEvent
В данном примере создается класс MyEventArgs, производный от класса EventArgs. В классе MyEventArgs добавляется лишь одно его собственное поле: EventNum. Затем объявляется делегат MyEventHandler, принимающий два параметра, требующиеся для среды .NET Framework. Как пояснялось выше, первый параметр содержит ссыл ку на объект, формирующий событие, а второй параметр — ссылку на объект класса EventArgs или производного от него класса. Обработчики событий Handler, опре деляемые в классах X и Y, принимают параметры тех же самых типов.
В классе MyEvent объявляется событие SomeEvent типа MyEventHandler. Это
событие запускается в методе OnSomeEvent с помощью делегата SomeEvent, ко
торому в качестве первого аргумента передается ссылка this, а вторым аргумен
том служит экземпляр объекта типа MyEventArgs. Таким образом, делегату типа
MyEventHandler передаются надлежащие аргументы в соответствии с требованиями
совместимости со средой .NET.
Применение делегатов EventHandler