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

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

Читайте также:
  1. SAE - классы вязкости моторных масел
  2. А если человек хочет нравиться многим одновременно? Ну, тогда его тело должно стать большим, чтобы каждому хватило по куску.
  3. Абстрактные классы
  4. Августовский путч. Хронология событий
  5. Алгебра событий
  6. Алгебра событий
  7. Амнезия событий раннего детство и Эдипов комплекс 1 7
  8. Виды туризма и классы обслуживания
  9. ВХОД ЗА БОЛЬШИМИ ЧАСАМИ
  10. Г. Цена, по которой продажа ведется отдельными небольшими партиями
  11. Где Николай II был в начале февральских событий 1917 года?
  12. Глава 27. Горизонт событий

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

public event <Имя Делегата> <Имя события>
{
add {...}
remove {...}
}

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

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

class ClassWithManyEvents
{
//хэш таблица для хранения делегатов
Hashtable DStore = new Hashtable();

// Генерируемые события:
public event EventHandler Ev1
{
add{ DStore["Ev1"]= (EventHandler)DStore["Ev1"]+ value; }
remove{ DStore["Ev1"]= (EventHandler)DStore["Ev1"]- value; }
}
public event EventHandler Ev2
{
add{ DStore["Ev2"]= (EventHandler)DStore["Ev2"]+ value; }
remove{ DStore["Ev2"]= (EventHandler)DStore["Ev2"]- value; }
}
public event EventHandler Ev3
{
add{ DStore["Ev3"]= (EventHandler)DStore["Ev3"]+ value; }
remove{ DStore["Ev3"]= (EventHandler)DStore["Ev3"]- value; }
}
public event EventHandler 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);
}
}

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

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

class ReceiverEvs
{
private ClassWithManyEvents manyEvs; //Ссылка на класс, генерирующий события
public ReceiverEvs(ClassWithManyEvents manyEvs) //Конструктор
{
this.manyEvs = manyEvs;
OnConnect();// Подключение к обработке события
}

// метод подключения("подписки") к обработке события
public void OnConnect()
{
СlassWithmanyEvs.Ev1 += new EventHandler(H1);
СlassWith manyEvs.Ev2 += new EventHandler(H2);
СlassWithmanyEvs.Ev3 += new EventHandler(H3);
ClassWithmanyEvs.Ev4 += new EventHandler(H4);
}

// Методы обработки события:
public void H1(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"); }
}

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

public void TestManyEvents()
{
ClassWithManyEvents me = new ClassWithManyEvents();
ReceiverEvs revs = new ReceiverEvs(me);
me.SimulateEvs();
}

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


1 | 2 | 3 | 4 | 5 | 6 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.)