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

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

Жанры

Полное руководство. С# 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; } }

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

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Вперед в прошлое 6

Ратманов Денис
6. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 6

Архил...? Книга 2

Кожевников Павел
2. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...? Книга 2

Чемпион

Демиров Леонид
3. Мания крафта
Фантастика:
фэнтези
рпг
5.38
рейтинг книги
Чемпион

Назад в СССР 5

Дамиров Рафаэль
5. Курсант
Фантастика:
попаданцы
альтернативная история
6.64
рейтинг книги
Назад в СССР 5

Я граф. Книга XII

Дрейк Сириус
12. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я граф. Книга XII

Матабар

Клеванский Кирилл Сергеевич
1. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар

Титан империи 3

Артемов Александр Александрович
3. Титан Империи
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Титан империи 3

Темный Охотник

Розальев Андрей
1. КО: Темный охотник
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Охотник

Вираж бытия

Ланцов Михаил Алексеевич
1. Фрунзе
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.86
рейтинг книги
Вираж бытия

Мастер Разума II

Кронос Александр
2. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.75
рейтинг книги
Мастер Разума II

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

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

Большие дела

Ромов Дмитрий
7. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Большие дела

Я тебя верну

Вечная Ольга
2. Сага о подсолнухах
Любовные романы:
современные любовные романы
эро литература
5.50
рейтинг книги
Я тебя верну