WWW.EL.Z-PDF.RU
БИБЛИОТЕКА  БЕСПЛАТНЫХ  МАТЕРИАЛОВ - Онлайн документы
 


«Листинг 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Aeroport{ public class Tablo { ...»

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

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

----------------Листинг 1--------------------

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34 class Aeroport{

public class Tablo {

public void Update(string info)

{

//ToDo: Tablo }

}

private Tablo t1 = new Tablo();

private List<Person> persons = new List<Person>();

public Aeroport()

{

persons.Add(new Person());

persons.Add(new Person());

persons.Add(new Person());

}

public void UpdateTablo()

{

t1.Update("Updated");

}

static void Main(string[] args)

{

Aeroport aer = new Aeroport();

aer.UpdateTablo();

}

}

class Person

{

public void Look()

{

Console.WriteLine("I can see");

}

}

В Листинге 1 (строка 1) описан Класс Aeroport, внутри него содержится класс Tablo. Далее объявляем и создаем объект класса Tablo (строка 10).

В строке 28 описываем класс Person, объявляем и создаем список объектов типа Person в конструкторе класса Aeroport (строка 11). Класс List в языке C# позволяет хранить список объектов одного типа, в данном случае – объекты типа Person. Добавляем в конструкторе класса Aeroport в список persons 3-х пассажиров (строки 12-17).

В строке 18 создаем открытый метод UpdateTablo(), в котором вызывается метод Update(string info) для объекта t1 типа Tablo, т.е. происходит изменение табло.

В функции Main() создаем объект aer типа Aeroport и через него вызываем метод UpdateTablo() (строка 25).

Теперь нужно как-то заставить список пассажиров реагировать на работу данного метода UpdateTablo(), причем только тех, которые смотрят на табло в данный момент. Т.е. должен быть какой-то механизм, который позволяет объекту типа Tablo отправлять сообщения всем другим объектам, которые подписались на событие Update(). Это может быть сделано с помощью делегатов.

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

В языке C++ есть такое понятие как указатели на функции [указатели на функции с++], т.е. формально, если бы здесь были указатели на функции, то в классе Tablo можно было бы такой указатель объявить.

Если объект класса Person хочет смотреть на табло, то он передает свой метод в указатель на функцию внутрь класса Tablo, а класс Tablo, когда вызывается метод Update(), вызывает необходимый метод, на который ссылается указатель.

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

Таким образом, нам нужно создать некоторый объект-делегат, содержащий набор ссылок на методы внешних объектов, а затем, используя его, вызвать все методы внешних объектов. В C# существует специальный класс, который называется Delegate, который является базовым классом для всех потенциальных классов, способных хранить ссылки на внешние методы.

Реализация (Листинг 2):

Создается специальный класс UpdateEvent (строка 1)(наследник класса Delegate), позволяющий хранить ссылки на методы заданной сигнатуры: void f(), т.е. возвращающие void и не принимающие никаких параметров. Объект данного класса служит для реализации подписки.

----------------Листинг 2--------------------

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33 class UpdateEvent : Delegate

{

void f();

}

public class Tablo {

public UpdateEvent updateEvent;

public void Update(string info)

{

//ToDo: Tablo }

}

private Tablo t1 = new Tablo();

private List<Person> persons = new List<Person>();

public Aeroport()

{

persons.Add(new Person());

persons.Add(new Person());

persons.Add(new Person());

}

public void UpdateTablo()

{

t1.Update("Updated");

t1.updateEvent += …;

}

static void Main(string[] args)

{

Aeroport aer = new Aeroport();

aer.UpdateTablo();

}

}

В строке 8 создается объект updateEvent типа UpdateEvent. Этот объект способен хранить ссылки на внешние методы, заданные сигнатурой (void f()) и инициировать вызов этих внешних методов.

В функции UpdateTablo() происходит вызов функции изменения табло: t1.Update("Updated"). Заметим, что с помощью операции t1.updateEvent +=… впоследствии в список событий можно включить необходимый метод внешнего объекта (строка 26), однако так как класс UpdateEvent создается нами вручную, все операции необходимо перегружать.

Вместо написания нового класса в.NET разрешили создавать делегаты с помощью одной строчки кода:

class Aeroport {

public delegate void UpdateEvent();

}

При обработке компилятором этой строчки автоматически создается класс типа UpdateEvent, который наследуется от класса Delegate, автоматически реализует все методы по добавлению, удалению и вызову внешних методов по цепочке.

Ключевое слово delegate означает, что будет создан класс. Сигнатура метода – void, без параметров.

UpdateEvent – это имя класса, который будет сгенерирован. Именно объект этого класса мы должны создать в классе Tablo, что позволит хранить ссылки на внешние методы.

---------------------Листинг 3---------------------

class Aeroport {

public delegate void UpdateEvent();

public class Tablo {

public UpdateEvent updateEvent;

public void Update(string info)

{

//ToDo: Tablo }

}

private Tablo t1 = new Tablo();

private List<Person> persons = new List<Person>();

public Aeroport()

{

persons.Add(new Person());

persons.Add(new Person());

persons.Add(new Person());

t1.updateEvent = persons[0].Look;

}

} Если нужно добавить и методы других пассажиров, тогда операция «=» затрет первый метод. Чтобы этого не случилось вместо оператора «=» нужно писать «+=»: t1.updateEvent += persons[0].Look;

public Aeroport()

{

persons.Add(new Person());

persons.Add(new Person());

persons.Add(new Person());

t1.updateEvent += persons[0].Look;

t1.updateEvent += persons[1].Look;

t1.updateEvent += persons[2].Look;

}

Теперь, когда табло обновляется, мы можем, используя updateEvent() – инициализировать вызов методов внешних объектов:

public class Tablo {

public UpdateEvent updateEvent;

public void Update(string info)

{

//ToDo: Tablo if (updateEvent !=null)// проверка, есть ли объекты, которые //подписались на данное событие

updateEvent();

}

}

У нас есть объект класса Aeroport, во время конструирования этого класса создается 3 человека, все 3 человека подписываются на делегат updateEvent, который содержит ссылки на методы сигнатуры, возвращающей void и без параметров и инициируется тогда, когда происходит какое-то обновление на Tablo t1.

Таким образом, табло не знает, кто на него смотрит, но может отправить нотификацию всем тем методам, которые на него подписаны.

Для того чтобы отписаться от события нужно использовать оператор «-=»: t1.updateEvent -= persons[2].Look.

Поскольку делегат является классом, то его можно объявить в любом месте программы.

Общий алгоритм использования делегатов:

создать класс:

public delegate void UpdateEvent();

создать объекты этого класса:

public UpdateEvent updateEvent;

добавить методы-подписчики:

t1.updateEvent += persons[0].Look;

t1.updateEvent += persons[2].Look;

удалить методы-подписчики:

t1.updateEvent -= persons[2].Look;

Есть возможность инициализировать делегат анонимным методом, т.е. не описывать метод снаружи, а сразу же присвоить ссылки на метод заданной сигнатуры:

myDelegate Instance += new myDelegate (delegate (int parameter)

{

// Perform operation

Return 10;

}

Рассмотренный механизм позволяет реализовывать модель событий, с помощью него можно реализовывать различные события, в том числе и обработку нажатия на кнопки:public delegate void UpdateEvent (object e, EventArgs args),

где e – объект, инициировавший событие, а args – дополнительные аргументы, уточняющие, например, какая именно кнопка была нажата.

Вернемся к Листингу 3. Для того чтобы у пассажиров была возможность подписки на событие изменения табло, ссылка на делегат должна быть объявлена с модификатором public:

public UpdateEvent updateEvent, тогда при подписке на событие можно написать так:

t1.updateEvent += persons[0].Look;

t1.updateEvent = null;

То есть первый пассажир подписался на событие, а кто-то пришел и унёс табло :). Таким образом любой объект может отписать от событий всех зарегистрированных пользователей, поэтому ссылку на делегат необходимо объявлять с модификатором private.

В этом случае, мы снова приходим к тому, что нужно добавить 2 метода: AddEvent() и RemoveEvent(), а следовательно и перегружать операторы «+=», «-=».

Вместо этого разработчики C# предложили такую конструкцию:

private event UpdateEvent updateEvent;

При обработки данной строки кода автоматически создадутся методы AddEvent(), RemoveEvent(), что позволяет сохранить такой же синтаксис, но в этом случае объекты на смогут работать с обычным присваиванием.

Похожие работы:

«ПРОЕКТНАЯ ДЕКЛАРАЦИЯ по строительству трех этажного четырех секционного жилого дома № 17 общей площадью 3521 кв.м. I-ой очереди строительства малоэтажного жилого комплекса "Березовая роща": Московская область, Раменский район, г.п.Раменское, земельный участок расположен в восточной части кадастрового кв...»

«Безформата Будущее гражданской обороны Поделиться. left0left0left0left0left0Фото: 31.mchs.gov.ruВ преддверии празднования 82-ой годовщины со дня образования гражданской обороны России в Учебно-методическом центре по ГОЧС Белгородской области проходят мероп...»

«ИНСТРУКЦИЯ ПО НАСТРОЙКЕ УСТРОЙСТВ SCANTECH SG-15Из каталога Configuration Tool диска, прилагаемого к каждому экземпляру Scantech SG-15, запускается приложение SG15Config:После запуска приложения из панели меню, вызывается функция поиска в локальной сети подключенных устройств Scantech SG-15 путем нажатия кнопки “Scan”: ! Все настраиваемые...»

«Содержание Введение 1 Математическое моделирование технических объектов1.1 Понятие математической модели1.2. Понятие математических моделей, их классификация и свойства1.3 Функции системы MathCAD1.4 Переменные в MathCAD1.5 Решение уравнений с использованием функции FIND, MINER1.6 Исследование функций на экстремум1.7 Графики в Math...»

«Ассоциация проектировщиков Саморегулируемая организация "Региональное Объединение Проектировщиков" (Ассоциация СРО "РОП") П р о т о к о л № 512 заседания Совета Ассоциации проектировщиков Саморегулируемой организации "Региональное Объединение Проектировщиков" 12.01.2017 г. Место проведения заседания: г. Москва, Кры...»

«СОГЛАСОВАНОУТВЕРЖДАЮ Председатель профкома Директор школы_Г.В.ПанасюкГ.Н.Царёв"_"_20г.""20г.протокол заседанияпрофкома от № ИНСТРУКЦИЯ № по охране труда для кухонного рабочего МБОУСШ №781. Общие требования безопасности1.1. На основании настоящей типовой инструкции разрабатывае...»

«ВЕРХОВНЫЙ СУД РОССИЙСКОЙ ФЕДЕРАЦИИ Именем Российской ФедерацииРЕШЕНИЕ от 8 августа 2012 г. N АКПИ12-937Верховный Суд Российской Федерации в составе: судьи Верховного Суда Российской Федерации Петровой Т.А., при секретаре И., с участием прокурора Масаловой Л.Ф., рассмотрев в открытом судебном заседании гражд...»

«ДОГОВОР № FORMTEXT 00участия в долевом строительстве г.Ковров " FORMTEXT 00"  FORMTEXT август 20 FORMTEXT 15 годаОбщество с ограниченной ответственностью "СК Континент" (далее – "Застройщик") от имени которо...»

«ПРОТОКОЛ № 30/05/2016 Заседания Дисциплинарной комиссии Некоммерческого партнерства Саморегулируемой организации "Региональное Объединение Проектировщиков" (Далее НП СРО "РОП", Партнерство) г. Москва "30" мая 2016 г.ПРИСУТСТВОВАЛИ:1. Султанова А.А. – Член Дисциплинарной комиссии НП СРО "РОП"; Председатель Ди...»

«1762760-3175000 КБСО TEA расширение TCL для тестирования процессоров DSP & ARM фирмы Texas Instruments с применением интерфейса JTAG шифр: “CCS 2.0” Program Specification Edition 1.0 Дол...»







 
2018 www.el.z-pdf.ru - «Библиотека бесплатных материалов - онлайн документы»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 2-3 рабочих дней удалим его.