Выбрать главу

    public FireMen(TownWithEvents TWE)

    {

        this.MyNativeTown=TWE;

        MyNativeTown.FireEvent += new

             FireEventHandler(FireHandler);

     }

     private void FireHandler(object Sender, int time, int build)

     {

         Console.WriteLine("Fire at day {0}, in build {1}!", time, build);

     }

     public void GoOutO

     {

          MyNativeTown.FireEvent — = new FireEventHandler(FireHandler);

     }

}//FireMan

В классе Fireman есть ссылка на объект класса TownWithEvents, создающий события. Сам объект передается в конструкторе класса. Здесь же происходит присоединение обработчика события к event-объекту. Обработчик события FireHandler выводит сообщение на консоль.

Классы с событиями, допустимые в каркасе. Net Framework

Если создавать повторно используемые компоненты с событиями, работающие не только в проекте С#, то необходимо удовлетворять некоторым ограничениям. Эти требования предъявляются к делегату; они носят, скорее, синтаксический характер, не ограничивая существа дела.

Перечислю эти ограничения:

• делегат, задающий тип события, должен иметь фиксированную сигнатуру из двух аргументов:

delegate <Имя_делегата> (object sender, <Тип_аргументов> args);

• первый аргумент задает объект sender, создающий сообщение. Второй аргумент args задает остальные аргументы — входные и выходные, — передаваемые обработчику. Тип этого аргумента должен задаваться классом, производным от встроенного в .Net Framework класса EventArgs.

Если обработчику никаких дополнительных аргументов не передается, то следует просто указать класс EventArgs, передавая null в качестве фактического аргумента при включении события;

• рекомендуемое имя делегата — составное, начинающееся именем события, после которого следует слово EventHandier, например, FireEventHandler. Если никаких дополнительных аргументов обработчику не передается, то тогда можно вообще делегата не объявлять, а пользоваться стандартным делегатом с именем EventHandier.

Пример "Списки с событиями"

В этом примере строится класс ListwithChangedEvent, являющийся потомком встроенного класса ArrayList, который позволяет работать со списками. В класс добавляется событие changed, сигнализирующее обо всех изменениях элементов списка. Строятся два класса — Receiver1 и Receiver2, получающие сообщения. В примере рассматривается взаимодействие нескольких объектов: два объекта посылают сообщения, три — принимают.

Начнем с объявления делегата:

// Объявление делегата

public delegate void ChangedEventHandler(object sender,

                                  ChangedEventArgs args);

Здесь объявлен делегат ChangedEventHandler, по всем правилам хорошего стиля — его имя и его форма соответствует всем требованиям. Второй аргумент, задающий аргументы события, принадлежит классу ChangedEventArgs, производному от встроенного класса EventArgs. Рассмотрим, как устроен этот производный класс:

public class ChangedEventArgs: EventArgs

{

    private object item;

    private bool permit;

    public object Item

    {

        get {return(item);}

        set { item = value;}

     }

     public bool Permit

     {

         get {return(permit);}

         set { permit = value;}

     }

}//class ChangedEventArgs

У класса два закрытых свойства, доступ к которым осуществляется через процедуры-свойства get и set. Конечно, можно было бы в данной ситуации сделать их просто public — общедоступными. Свойство item задает входной аргумент события, передаваемый обработчику события. Булево свойство Permit задает выходной аргумент события, получающий в обработчике значение True, если обработчик события дает добро на изменение элемента.

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

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