Внутренний механизм поддержки событий
Лабораторная работа № 12.2
Тема:Разработка программ реализующих паттерн наблюдатель при помощи механизма событий. Цель работы: Формирование умений и навыков использования событий в программе.
Время на выполнение работы: 2 часа Этапы работы: I.Ознакомится с теоретическими сведениями II.Выполнить задания. III.Ответить на контрольные вопросы
I Теоретические сведения Как устроены события и зачем они нужны Начнем изучение с несколько идеализированного примера. Допустим, имеется некоторый компонент, и пускай для упрощения примера это будет банальная кнопка. Всем известно, что на кнопки можно нажимать. При нажатии кнопки происходит событие "щелчок", о котором необходимо обязательно уведомлять пользователя нашего компонента. Для этого введем в класс, представляющий компонент-кнопку, общедоступное поле Click, являющееся экземпляром делегата. И каждый раз, когда будет происходить соответствующее событие, будем обращаться к этому делегату. А он, в свою очередь, будет вызывать прикрепленные к нему функции и методы. Приведу код (листинг 11). Листинг 11. Пример события на основе делегата.
Теперь пользователи нашего класса смогут присоединить свои функции к переменной-полю экземпляра делегата и получить уведомление о произошедшем событии. Но поскольку среда .NET является объектно-ориентированной, мы обязаны соблюдать правила инкапсуляции полей. Соответственно, необходимо ввести дополнительные методы, обслуживающие поле-экземпляр делегата и контролирующие все производимые над ним операции, а само поле полагается сделать закрытым. Сделаем это следующим образом — добавим две функции add_Click и remove_Click, которые, соответственно, будут добавлять и убирать события в очередь делегата. Новый код представлен в листинге 12. Листинг 12. Пример события на основе делегата, с поддержкой инкапсуляции полей.
Теперь наш компонент удовлетворяет основным парадигмам объектно-ориентированного программирования. Только вот, его код стал уж больно громоздким и его использование не будет столь наглядным, как прежде. События .NET Понимали это и разработчики, создававшие среду .NET. Для решения этой задачи они ввели специальное поле-событие, которое автоматически вводит поле-делегат и два дополнительных метода, обслуживающих его. Таким образом, автоматически реализуется представленная выше модель. В языке высокого уровня C# определение таких полей осуществляется при помощи ключевого слова event. Также компилятор берет на себя заботу о работе с этими полями-событиями, благодаря чему к ним можно прибавлять и вычитать делегаты, хотя они, по сути дела, таковыми не являются. Приведем наглядный пример использования полей-событий (листинг 13). Листинг 13. Использование полей-событий.
В результате работы приложения, на консоль будет выведена следующая строка:
Таким образом, работа с событиями представляется предельно простой. Она, по сути дела, ничем не отличается от взаимодействия с обыкновенными делегатами. Внутренний механизм поддержки событий Рассмотрим, какой код поддержки события был создан компилятором. Для этого изучим IL- код. Во-первых, компилятор создал поле-делегат, в котором хранятся все зарегистрированные обработчики события.
Обратите внимание, что поле является закрытым и может быть использовано только из самого класса, исключая даже его потомков (private). Также компилятор создал одноименное специализированное свойство, в котором указаны методы, реализующие внешнюю работу с данным событием. Причем необходимо отметить, что это свойство по умолчанию является общедоступным.
Дабы не утомлять читателя излишним чтением IL-листингов, приведем код методов на языке C#.
Методы будут использоваться только при работе с событием извне класса. Внутри же используется прямое обращение к полю Click, что несколько быстрее, чем вызов методов add_Click и remove_Click. Здесь можно усмотреть борьбу команды разработчиков компилятора С# за производительность создаваемых им программ. Чтобы подтвердить сказанное, приведем IL-код функции SimulateClick, которая непосредственно обращается к событию из самого класса, если быть до конца точным, то не к самому событию, а к полю-экземпляру делегата.
Обратите внимание на выделенную в коде инструкцию ldfld — она предназначена для работы с полями объекта. Также в листинге отсутствуют обращения к функциям add_Click и remove_Click. Что и требовалось доказать!
Популярное: Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение... Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы... Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (324)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |