Студопедия — Volatile 13 страница. b.Click += new EventHandler( );
Студопедия Главная Случайная страница Обратная связь

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

Volatile 13 страница. b.Click += new EventHandler( );






b.Click += new EventHandler(…);

где делегат добавляется к списку вызовов события Click, и в

b.Click –= new EventHandler(…);

где делегат удаляется из списка вызовов события Click.

При компиляции события, подобного полю, компилятор автоматически создает хранилище для хранения делегата и создает методы доступа для события, добавляющие или удаляющие обработчики событий поля делегата. Чтобы быть потокобезопасными, операции добавления и удаления выполняются при блокировке (§8.12) содержащего объекта для события экземпляра или объекта типа (§7.5.10.6) для статического события.

Так, объявление события экземпляра вида:

class X
{
public event D Ev;
}

можно скомпилировать в нечто, эквивалентное:

class X
{
private D __Ev; // поле для хранения делегата

public event D Ev {
add {
lock(this) { __Ev = __Ev + value; }
}

remove {
lock(this) { __Ev = __Ev - value; }
}
}
}

Внутри класса X ссылки на Ev компилируются в ссылки на скрытое поле __Ev. Имя "__Ev" произвольное; скрытое поле могло бы иметь любое имя или вообще его не иметь.

Аналогично объявление статического события вида:

class X
{
public static event D Ev;
}

можно скомпилировать в нечто, эквивалентное:

class X
{
private static D __Ev; // поле для хранения делегата

public static event D Ev {
add {
lock(typeof(X)) { __Ev = __Ev + value; }
}

remove {
lock(typeof(X)) { __Ev = __Ev - value; }
}
}
}

10.8.2 Методы доступа к событиям

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

Объявления_методов_доступа_к_событиям события указывают исполняемые операторы, связанные с добавлением и удалением обработчиков событий.

Объявления методов доступа состоят из объявления_метода_доступа_add и объявления_метода_доступа_remove. Каждое объявление метода доступа состоит из лексемы add или remove, за которой следует блок. В блоке, связанном с объявлением_метода_доступа_add, указываются операторы, выполняемые при добавлении обработчика событий, а в блоке, связанном с объявлением_метода_доступа_remove, указываются операторы, выполняемые при удалении обработчика событий.

Каждое объявление_метода_доступа_add и объявление_метода_доступа_remove соответствует методу с одним параметром значения типа события и типом возвращаемого значения void. Неявный параметр метода доступа к событию называется value. Когда событие используется в назначении события, используется соответствующий метод доступа к событию. В частности, если оператором присваивания является +=, используется метод доступа add, а если оператор присваивания -=, используется метод доступа remove. В любом случае правый операнд оператора присваивания используется в качестве аргумента метода доступа к событию. Блок объявления_метода_доступа_add или объявления_метода_доступа_remove должен соответствовать правилам для методов void, описанным в §10.6.10. В частности, операторам return в таком блоке запрещено указывать выражение.

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

В примере

class Control: Component
{
// Уникальные ключи для событий
static readonly object mouseDownEventKey = new object();
static readonly object mouseUpEventKey = new object();

// Вернуть обработчик событий, связанный с ключом
protected Delegate GetEventHandler(object key) {...}

// Добавить обработчик событий, связанный с ключом
protected void AddEventHandler(object key, Delegate handler) {...}

// Удалить обработчик событий, связанный с ключом
protected void RemoveEventHandler(object key, Delegate handler) {...}

// Событие MouseDown
public event MouseEventHandler MouseDown {
add { AddEventHandler(mouseDownEventKey, value); }
remove { RemoveEventHandler(mouseDownEventKey, value); }
}

// Событие MouseUp
public event MouseEventHandler MouseUp {
add { AddEventHandler(mouseUpEventKey, value); }
remove { RemoveEventHandler(mouseUpEventKey, value); }
}

// Вызвать событие MouseUp
protected void OnMouseUp(MouseEventArgs args) {
MouseEventHandler handler;
handler = (MouseEventHandler)GetEventHandler(mouseUpEventKey);
if (handler!= null)
handler(this, args);
}
}

класс Control реализует механизм внутреннего хранилища для событий. Метод AddEventHandler связывает значение делегата с ключом, метод GetEventHandler возвращает делегат, в данный момент связанный с ключом, а метод RemoveEventHandler удаляет делегат в качестве обработчика событий для указанного события. Предположительно, лежащий в основе механизм хранилища разработан так, что отсутствуют затраты на связывание значения делегата null с ключом, и таким образом необрабатываемые события не расходуют емкость хранилища.

10.8.3 Статические события и события экземпляров

Если в объявление события включен модификатор static, событие называют статическим событием. Если нет модификатора static, событие называют событием экземпляра.

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

Событие экземпляра связано с данным экземпляром класса, и к этому экземпляру можно обращаться как к this (§7.5.7) в методах доступа этого события.

Когда к событию обращаются через доступ_к_члену (§7.5.4) вида E.M, если M является статическим событием, E должно означать тип, содержащий M, а если M является событием экземпляра, E должно означать экземпляр типа, содержащего M.

Различия между статическими членами и членами экземпляров обсуждаются далее в §10.3.7.

10.8.4 Виртуальные, запечатанные, переопределяющие и абстрактные методы доступа

Объявление события как virtual указывает, что методы доступа этого события являются виртуальными. Модификатор virtual применяется к обоим методам доступа события.

Объявление события как abstract указывает, что методы доступа события являются виртуальными, но не предоставляет фактическую реализацию методов доступа. Вместо этого требуются не абстрактные производные классы для предоставления их собственной реализации для методов доступа посредством переопределения события. Поскольку объявление абстрактного события не предоставляет фактическую реализацию, оно не может предоставить разделенные скобками объявления_методов_доступа_к_событиям.







Дата добавления: 2015-09-07; просмотров: 415. Нарушение авторских прав; Мы поможем в написании вашей работы!



Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

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

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

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

Тема: Кинематика поступательного и вращательного движения. 1. Твердое тело начинает вращаться вокруг оси Z с угловой скоростью, проекция которой изменяется со временем 1. Твердое тело начинает вращаться вокруг оси Z с угловой скоростью...

Условия приобретения статуса индивидуального предпринимателя. В соответствии с п. 1 ст. 23 ГК РФ гражданин вправе заниматься предпринимательской деятельностью без образования юридического лица с момента государственной регистрации в качестве индивидуального предпринимателя. Каковы же условия такой регистрации и...

Влияние первой русской революции 1905-1907 гг. на Казахстан. Революция в России (1905-1907 гг.), дала первый толчок политическому пробуждению трудящихся Казахстана, развитию национально-освободительного рабочего движения против гнета. В Казахстане, находившемся далеко от политических центров Российской империи...

Виды сухожильных швов После выделения культи сухожилия и эвакуации гематомы приступают к восстановлению целостности сухожилия...

КОНСТРУКЦИЯ КОЛЕСНОЙ ПАРЫ ВАГОНА Тип колёсной пары определяется типом оси и диаметром колес. Согласно ГОСТ 4835-2006* устанавливаются типы колесных пар для грузовых вагонов с осями РУ1Ш и РВ2Ш и колесами диаметром по кругу катания 957 мм. Номинальный диаметр колеса – 950 мм...

Studopedia.info - Студопедия - 2014-2024 год . (0.017 сек.) русская версия | украинская версия