Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
тюмгу / Лекции КБ ИБАС 1 курс 2 семестр / лекция18 Безопасность 2018.ppt
Скачиваний:
15
Добавлен:
08.12.2019
Размер:
653.82 Кб
Скачать

Описание классов - наблюдателей:

class ObsA

// класс-наблюдатель 1

{

 

string Name;

public ObsA(string name) { Name = name; }

public void Do(object o) // реакция на событие источника (o)

{

Console.WriteLine(" ObsA-" + Name + " : Вижу, что ухнул" + o.ToString());

}

}

class ObsB // класс-наблюдатель 2

{

public static void See(object o) // реакция на событие

{

Console.WriteLine(" ObsB тоже видит, что ухнул" + o.ToString());

}

}

Основная программа:

class Program

 

 

 

{

 

 

 

static void Main()

 

 

 

{

 

 

 

Subj s = new Subj();

 

//объект класса-источника

событий

 

 

 

ObsA o1 = new ObsA("1");

 

//объекты

ObsA o2 = new ObsA("2");

 

//класса-наблюдателя

// регистрация методов наблюдателей в источнике

s.Register(new Del(o1.Do));

// экземлярного

s.Register(new Del(ObsB.See)); // статического

s.OPPA();

//

 

инициирование события

s.Register(new

 

 

 

s.OPPA();

 

 

 

}

 

 

 

}

 

 

 

Для обеспечения обратной связи между наблюдателем и источником делегат объявлен с параметром типа object, через который в вызываемый метод передается ссылка на вызывающий объект. Следовательно, в вызываемом методе можно получать информацию о состоянии вызывающего объекта и посылать ему сообщения.

Связь «источник — наблюдатель» устанавливается во время выполнения программы для каждого объекта по отдельности. Если наблюдатель больше не хочет получать уведомления от источника, можно удалить соответствующий метод из списка делегата (пула) с помощью метода Remove или перегруженной операции вычитания, например:

public void UnRegister( Del d ) // удаление делегата

{

dels -= d;

}

Возможные операции с делегатами

Обозначение [d1, d2, d3] подразумевает комбинированный делегат, который состоит из трёх простых именно в таком порядке, т.е. при вызове сначала будет вызван d1, потом d2, а затем d3.

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

объединяться при помощи статического метода

Delegate.Combine.

Операция вычитания также имеет альтернативу в виде статического метода

Delegate.Remove.

События

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

События позволят одному объекту посылать другим объектам уведомления об изменении своего состояния. При этом для объектов, являющихся наблюдателями события, активизируются методы-обработчики этого события.

Обработчики должны быть зарегистрированы в объекте- источнике события (в пуле). Таким образом, механизм событий формализует на языковом уровне паттерн «наблюдатель».

Механизм событий можно также описать с помощью модели «издатель-подписчик»: один класс, являющийся отправителем (sender) сообщения, публикует события, которые он может инициировать, а другие классы, являющиеся получателями (receivers) сообщения, подписываются на получение этих событий.

Событием может быть нажатие кнопки, выбор команды меню, завершение какой-либо операции и т. п. Т.е., если происходит что-то важное, программа должна отреагировать.

Порядок возникновения событий предсказать невозможно. Система ждет возникновения события, а затем предпринимает действия по его обработке. Метод, реагирующий на события, называется обработчиком события (event handler).

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

В языке С# любой объект может опубликовать набор событий, а другие классы могут на них подписаться. Когда публикующий класс вызывает событие, все подписавшиеся классы уведомляются об этом.

События и делегаты

Создание события в классе состоит из следующих частей:

описание делегата, задающего сигнатуру обработчиков

событий;

описание события – элемента класса

источника(издателя);

описание метода (методов), инициирующих событие.

Класс-издатель определяет делегат, который должен быть

реализован классами-подписчиками. Когда возникает событие, методы подписчиков вызываются через этот пул этого делегата. Программист объявляет обработчик события как любой другой делегат.

Существует соглашение, по которому обработчики событий в .NET Framework возвращают void и принимают два параметра:

Первый - это источник события, то есть объект-издатель.

Вторым параметром передается объект, производный от класса EventArgs.

EventArgs является классом, базовым для всех классов параметров событий. Классы, производные от EventArgs, содержат информацию о возникшем событии.

Обычно достаточно базового класса EventArgs. Но, если с событием связаны дополнительные атрибуты/параметры, они указываются в классе производном от EventArgs.

Событие является свойством класса, опубликовавшего его.

Обработка события выполняется в классах-получателях сообщения. Для этого в них описываются методы- обработчики событий, сигнатура которых соответствует типу делегата.

Каждый объект, желающий получать сообщение, должен зарегистрировать в объекте-отправителе этот метод- обработчик.

Предположим, создается класс Clock, который с помощью события уведомляет классы-подписчики о том, что местное время изменилось (например, увеличилось на одну секунду). Назовем это событие OnSecondChange.

Событие и тип делегата для обработки события определяются следующим образом:

[модификаторы] event тип имя

Например: public event TimeChangeHandler OnChange;

В качестве модификатора указывается ключевое слово abstract, override, static, virtual или один из модификаторов права доступа, в данном случае public.

За модификатором стоит ключевое слово event.

Тип - это делегат, который должен быть связан с событием, в данном случае TimeChangeHandler.

Имя - имя события, в рассматриваемом примере это

OnChange.

Принято начинать имена событий с префикса On.

Описание : public event TimeChangeHandler OnChange;

означает, что OnChange является событием, реализованным с помощью делегата TimeChangeHandler.

Объявление этого делегата выглядит так: public delegate void TimeChangeHandler(

object clock,

EventArgs information);

Здесь объявляется делегат, который указывает, что обработчик события должен возвращать void и принимать два параметра: источник события (объект clock) и объект класса EventArgs.

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