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

на главную

Жанры

Интернет-журнал "Домашняя лаборатория", 2007 №9
Шрифт:

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

Классы с большим числом событий

Как было сказано, каждое событие класса представляется полем этого класса.

Если у класса много объявленных событий, а реально возникает лишь малая часть из них, то предпочтительнее динамический подход, когда память отводится только фактически возникшим событиям. Это несколько замедляет время выполнения, но экономит память. Решение зависит от того, что в данном контексте важнее — память или время. Для реализации динамического подхода в языке предусмотрена возможность задания пользовательских методов Add и Remove в момент объявления события. Это и есть другая форма объявления события, упоминавшаяся ранее. Вот ее примерный синтаксис:

public event <Имя Делегата> <Имя события>

{

add {…}

remove {… }

}

Оба метода должны быть реализованы, при этом для хранения делегатов используется некоторое хранилище. Именно так реализованы классы для большинства интерфейсных объектов, использующие хэш-таблицы для хранения делегатов.

Давайте построим небольшой пример, демонстрирующий такой способ объявления и работы с событиями. Вначале построим класс с несколькими событиями:

class ManyEvents

{

//хэш таблица для хранения делегатов

Hashtable DStore = new Hashtable;

public event EventHandier Evl

{

add

{

DStore["Evl"]= (EventHandier)DStore["Evl"]+ value;

}

remove

{

DStore["Evl"]= (EventHandier)DStore["Evl"] - value;

}

}

public event EventHandier Ev2

{

add

{

DStore["Ev2"]= (EventHandier)DStore["Ev2"]+ value;

}

remove

{

DStore["Ev2"]= (EventHandier)DStore["Ev2"] - value;

}

}

public event EventHandier Ev3

{

add

{

DStore["Ev3"]= (EventHandier)DStore["Ev3"]+ value;

}

remove

{

DStore["Ev3"]= (EventHandier)DStore["Ev3"] - value;

}

}

public event EventHandier Ev4

{

add

{

DStore["Ev4"]= (EventHandler)DStore["Ev4"] - value;

}

remove

}

DStore["Ev4"]= (EventHandler)DStore["Ev4"] - value;

}

}

public void SimulateEvs

{

EventHandler ev = (EventHandler) DStore["Ev1"];

if(ev!= null) ev(this, null);

ev = (EventHandler) DStore["Ev3"];

if(ev!= null) ev(this, null);

}

}//class ManyEvents

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

метод remove, выполняющий аналогичную операцию над соответствующим элементом хэш-таблицы. В классе определен также метод SimulateEvs, при вызове которого зажигаются два из четырех событий — Ev1 и Ev3.

Рассмотрим теперь класс ReceiverEvs, слушающий события. Этот класс построен по описанным ранее правилам. В нем есть ссылка на класс, создающий события; конструктор с параметром, которому передается реальный объект такого класса; четыре обработчика события — по одному на каждое, и метод OnConnect, связывающий обработчиков с событиями. Вот код класса:

class ReceiverEvs

{

private ManyEvents manyEvs;

public ReceiverEvs(ManyEvents manyEvs)

{

this.manyEvs = manyEvs;

OnConnect ;

}

public void OnConnect

{

manyEvs.Ev1 += new EventHandler(H1);

manyEvs.Ev2 += new EventHandler(H2);

manyEvs.Ev3 += new EventHandler (H3);

manyEvs.Ev4 += new EventHandler(H4);

}

public void HI (object s, EventArgs e)

{

Console.WriteLine("Событие Ev1");

}

public void H2 (object s, EventArgs e)

{

Console.WriteLine("Событие Ev2");

}

public void H3 (object s, EventArgs e)

{

Console.WriteLine("Событие Ev3");

}

public void H4 (object s, EventArgs e)

{

Console.WriteLine("Событие Ev4");

}

}//class ReceiverEvs

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

public void TestManyEvents

{

ManyEvents me = new ManyEvents ;

ReceiverEvs revs = new ReceiverEvs(me);

me.SimulateEvs;

}

Все работает предусмотренным образом.

Проект "Город и его службы"

Завершить лекцию о событиях хочется содержательным учебным проектом, в котором моделируется жизнь города, происходящие в нем события и реакция на них городских служб. Наша главная цель в данном проекте — еще раз показать, как возникающее событие, в данном случае — пожар в одном из домов города, обрабатывается по-разному городскими службами — пожарными, милицией, скорой помощью. Конечно, все упрощено, в реальном городе событиями являются не только пожары и преступления, но и более приятные ситуации: день города, открытие фестивалей и выставок, строительство новых театров и институтов.

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

public class NewTown

{

//свойства

private int build, BuildingNumber; //дом и число домов в городе

private int day, days; //Текущий день года

//городские службы

private Police policeman;

private Ambulance ambulanceman;

private FireDetect fireman;

//события в городе

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

Ротмистр Гордеев 2

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

Рота Его Величества

Дроздов Анатолий Федорович
Новые герои
Фантастика:
боевая фантастика
8.55
рейтинг книги
Рота Его Величества

Ваше Сиятельство 6

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

Расческа для лысого

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
8.52
рейтинг книги
Расческа для лысого

Архил…? Книга 3

Кожевников Павел
3. Архил...?
Фантастика:
фэнтези
попаданцы
альтернативная история
7.00
рейтинг книги
Архил…? Книга 3

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

Винокуров Юрий
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XV

Девяностые приближаются

Иванов Дмитрий
3. Девяностые
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Девяностые приближаются

Сила рода. Том 3

Вяч Павел
2. Претендент
Фантастика:
фэнтези
боевая фантастика
6.17
рейтинг книги
Сила рода. Том 3

«Три звезды» миллиардера. Отель для новобрачных

Тоцка Тала
2. Три звезды
Любовные романы:
современные любовные романы
7.50
рейтинг книги
«Три звезды» миллиардера. Отель для новобрачных

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

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

Архонт

Прокофьев Роман Юрьевич
5. Стеллар
Фантастика:
боевая фантастика
рпг
7.80
рейтинг книги
Архонт

Темный Патриарх Светлого Рода 4

Лисицин Евгений
4. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 4

Дайте поспать!

Матисов Павел
1. Вечный Сон
Фантастика:
юмористическое фэнтези
постапокалипсис
рпг
5.00
рейтинг книги
Дайте поспать!

Идеальный мир для Лекаря 18

Сапфир Олег
18. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 18