Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Делегаты и события






Наверное, вы уже заметили, что схема работы с событиями укладывается в механизм, определяемый делегатами. В C# каждое событие определяется делегатом, описывающим сигнатуру сообщения. Как и делегаты, события поддерживают групповую адресацию. Это дает возможность нескольким объектам реагировать на уведомление о событии. Объявление события - это двухэтапный процесс.

  • Вначале объявляется делегат - функциональный класс, задающий сигнатуру. Как отмечалось при рассмотрении делегатов, объявление делегата может быть помещено в некоторый класс, например, класс sender. Но чаще всего это объявление находится вне класса в пространстве имен. Поскольку одна и та же сигнатура может быть у разных событий, для них достаточно иметь одного делегата. Для некоторых событий можно использовать стандартные делегаты, встроенные в каркас. Тогда достаточно знать только их имена.
  • Если делегат определен, то в классе sender, создающем события, достаточно объявить событие как экземпляр соответствующего делегата. Это делается точно так же, как и при объявлении функциональных экземпляров делегата. Исключением является добавление служебного слова event. Формальный синтаксис объявления таков:
· [атрибуты] [модификаторы]event [тип, заданный делегатом] [имя события]

Вполне вероятно, что одно и то же событие будет зажигаться в разных методах класса в тот момент, когда возникнет одна из причин появления события. Поскольку действия по включению события могут повторяться, полезно в состав методов класса добавить защищенную процедуру, зажигающую событие. Даже если событие зажигается только в одной точке, написание такой процедуры считается признаком хорошего стиля. Этой процедуре обычно дается имя, начинающееся со слова On, после которого следует имя события. Будем называть такую процедуру On- процедурой. Она проста и состоит из вызова объявленного события, включенного в тест, который проверяет перед вызовом, есть ли хоть один обработчик события, способный принять соответствующее сообщение. Если таковых нет, то нечего включать событие. Вызов объявленного события называется зажиганием или включением события. Его можно рассматривать как посылку сообщения, как вызов метода клиента, обрабатывающего событие. Говоря более точно, сообщение посылается всем, кто готов принять это сообщение, и обрабатывать это сообщение будет не один метод, а все методы из списка вызовов, присоединившихся к событию. Такая возможность имеется у делегатов. Возможность комбинирования делегатов в полной мере проявляется при работе с событиями. Благодаря этой возможности одно и то же событие будет обрабатываться методами, принадлежащими разным классам receiver.

Последний шаг, который необходимо выполнить в классе sender, - в нужных методах класса вызвать процедуру On. Перед вызовом нужно определить значения входных аргументов события. После вызова может быть выполнен анализ выходных аргументов, определенных обработчиками события. Формально все просто: вызов процедуры On может быть сделан в любом методе класса в любой его точке, точно так же, как вызывается любой другой метод класса. Но с содержательной точки зрения это может быть самый сложный момент в проектировании класса с событиями.

public TownWithEvents(string name, int days, double snowProbability) { townName = name; this.days = days; this. snowProbability = snowProbability; }public void TownLife() { const string OK = " Снега не было."; bool wasSnow = false; for(int day = 1; day < days; day++) if (random.NextDouble() < snowProbability) { OnSnow(day); wasSnow = true; } if (! wasSnow) Console.WriteLine(OK); }

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.