Чтение онлайн

на главную - закладки

Жанры

Полное руководство. С# 4.0
Шрифт:

События являются членами класса и объявляются с помощью ключевого слова event. Чаще всего для этой цели используется следующая форма: event делегат_события имя_события;

где делегатсобытия обозначает имя делегата, используемого для поддержки собы тия, а имясобытия — конкретный объект объявляемого события.

Рассмотрим для начала очень простой пример. // Очень простой пример, демонстрирующий событие. using System; // Объявить тип делегата для события. delegate void MyEventHandler; // Объявить класс, содержащий событие. class MyEvent { public event MyEventHandler SomeEvent; // Этот метод вызывается для запуска события. public void OnSomeEvent { if(SomeEvent != null) SomeEvent; } } class EventDemo { // Обработчик события. static void Handler { Console.WriteLine("Произошло

событие"); } static void Main { MyEvent evt = new MyEvent; // Добавить метод Handler в список событий. evt.SomeEvent += Handler; // Запустить событие. evt.OnSomeEvent; } }

Вот какой результат получается при выполнении этого кода. Произошло событие

Несмотря на всю свою простоту, данный пример кода содержит все основные эле менты, необходимые для обработки событий. Он начинается с объявления типа деле гата для обработчика событий, как показано ниже. delegate void MyEventHandler;

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

Далее создается класс события MyEvent. В этом классе объявляется событие SomeEvent в следующей строке кода. public event MyEventHandler SomeEvent;

Обратите внимание на синтаксис этого объявления. Ключевое слово event уведом ляет компилятор о том, что объявляется событие.

Кроме того, в классе MyEvent объявляется метод OnSomeEvent, вызываемый для сигнализации о запуске события. Это означает, что он вызывается, когда происходит событие. В методе OnSomeEvent вызывается обработчик событий с помощью деле гата SomeEvent. if(SomeEvent != null) SomeEvent;

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

В классе EventDemo создается обработчик событий Handler. В данном простом примере обработчик событий просто выводит сообщение, но другие обработчики могут выполнять более содержательные функции. Далее в методе Main создается объект класса события MyEvent, a Handler регистрируется как обработчик этого события, добавляемый в список. MyEvent evt = new MyEvent; // Добавить метод Handler в список событий. evt.SomeEvent += Handler;

Обратите внимание на то, что обработчик добавляется в список с помощью опера тора +=. События поддерживают только операторы += и -=. В данном случае метод Handler является статическим, но в качестве обработчиков событий могут также служить методы экземпляра.

И наконец, событие запускается, как показано ниже. // Запустить событие. evt.OnSomeEvent;

Вызов метода OnSomeEvent приводит к вызову всех событий, зарегистрирован ных обработчиком. В данном случае зарегистрирован только один такой обработчик, но их может быть больше, как поясняется в следующем разделе. Пример групповой адресации события

Как и делегаты, события поддерживают групповую адресацию. Это дает возмож ность нескольким объектам реагировать на уведомление о событии. Ниже приведен пример групповой адресации события. // Продемонстрировать групповую адресацию события. using System; // Объявить тип делегата для события. delegate void MyEventHandler; // Объявить делегат, содержащий событие. class MyEvent { public event MyEventHandler SomeEvent; // Этот метод вызывается для запуска события. public void OnSomeEvent { if(SomeEvent != null) SomeEvent; } } class X { public void Xhandler { Console.WriteLine("Событие получено объектом класса X"); } } class Y { public void Yhandler { Console.WriteLine("Событие получено объектом класса Y"); } } class EventDemo2 { static void Handler { Console.WriteLine("Событие получено объектом класса EventDemo"); } static void Main { MyEvent evt = new MyEvent; X xOb = new X; Y yOb = new Y; // Добавить обработчики в список событий. evt.SomeEvent += Handler; evt.SomeEvent += xOb.Xhandler; evt.SomeEvent += yOb.Yhandler; // Запустить событие. evt.OnSomeEvent; Console.WriteLine; // Удалить обработчик. evt.SomeEvent -= xOb.Xhandler; evt.OnSomeEvent; } }

При

выполнении кода этого примера получается следующий результат. Событие получено объектом класса EventDemo Событие получено объектом класса X Событие получено объектом класса Y Событие получено объектом класса EventDemo Событие получено объектом класса Y

В данном примере создаются два дополнительных класса, X и Y, в которых также определяются обработчики событий, совместимые с делегатом MyEventHandler. Поэтому эти обработчики могут быть также включены в цепочку событий. Обратите внимание на то, что обработчики в классах X и Y не являются статическими. Это озна чает, что сначала должны быть созданы объекты каждого из этих классов, а затем в цепочку событий должны быть введены обработчики, связанные с их экземплярами. Об отличиях между обработчиками экземпляра и статическими обработчиками речь пойдет в следующем разделе. Методы экземпляра в сравнении со статическими методами в качестве обработчиков событий

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

В приведенной ниже программе создается класс X, в котором метод экземпляра определяется в качестве обработчика событий. Это означает, что каждый объект класса X должен быть зарегистрирован отдельно, чтобы получать уведомления о событиях. Для демонстрации этого факта в данной программе производится групповая адреса ция события трем отдельным объектам класса X. /* Уведомления о событиях получают отдельные объекты, когда метод экземпляра используется в качестве обработчика событий. */ using System; // Объявить тип делегата для события. delegate void MyEventHandler; // Объявить класс, содержащий событие. class MyEvent { public event MyEventHandler SomeEvent; // Этот метод вызывается для запуска события. public void OnSomeEvent { if(SomeEvent != null) SomeEvent; } } class X { int id; public X(int x) { id = x; } // Этот метод экземпляра предназначен в качестве обработчика событий. public void Xhandler { Console.WriteLine("Событие получено объектом " + id); } } class EventDemo3 { static void Main { MyEvent evt = new MyEvent; X o1 = new X(1); X o2 = new X(2); X o3 = new X(3); evt.SomeEvent += o1.Xhandler; evt.SomeEvent += o2.Xhandler; evt.SomeEvent += o3.Xhandler; // Запустить событие. evt.OnSomeEvent; } }

Выполнение кода из этого примера приводит к следующему результату. Событие получено объектом 1 Событие получено объектом 2 Событие получено объектом 3

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

С другой стороны, когда в качестве обработчика событий используется статический метод, события обрабатываются независимо от какого-либо объекта, как демонстриру ется в приведенном ниже примере программы. /* Уведомления о событии получает класс, когда статический метод используется в качестве обработчика событий. */ using System; // Объявить тип делегата для события. delegate void MyEventHandler; // Объявить класс, содержащий событие. class MyEvent { public event MyEventHandler SomeEvent; // Этот метод вызывается для запуска события. public void OnSomeEvent { if(SomeEvent != null) SomeEvent; } } class X { /* Этот статический метод предназначен в качестве обработчика событий. */ public static void Xhandler { Console.WriteLine("Событие получено классом."); } } class EventDemo4 { static void Main { MyEvent evt = new MyEvent; evt.SomeEvent += X.Xhandler; // Запустить событие. evt.OnSomeEvent; } }

Поделиться:
Популярные книги

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5