Головна |
Если свойство объявлено с помощью модификатора override, все переопределенные методы доступа должны быть доступны переопределяющему коду. Кроме того, объявленные уровни доступа для самого свойства или индексатора и его методов доступа должны соответствовать уровням доступа переопределенного члена и его методов доступа. Например:
public class B
{
public virtual int P {
protected set {...}
get {...}
}
}
public class D: B
{
public override int P {
protected set {...} // Необходимо задать protected
get {...} // Использование модификатора не допускается
}
}
10.8 События
Событие - это член, используемый классом или объектом для уведомления. Клиенты могут присоединять к событиям исполняемый код с помощью обработчиков событий.
События объявляются с помощью объявлений_событий:
объявление_события:
атрибутынеобязательно модификаторы_событийнеобязательно event тип деклараторы переменных ;
атрибутынеобязательно модификаторы_событийнеобязательно event тип имя_члена { объявления_методов_доступа_события }
модификаторы_событий:
модификатор_события
модификаторы_событий модификатор_события
модификатор_события:
new
public
protected
internal
private
static
virtual
sealed
override
abstract
extern
объявления_методов_доступа события:
объявление_метода_доступа_add объявление_метода_доступа_remove
объявление_метода_доступа_remove объявление_метода_доступа_add
объявление_метода_доступа_add:
атрибутынеобязательно add блок
объявление_метода_доступа_remove:
атрибутынеобязательно remove блок
Объявление_события может включать набор атрибутов (§17), допустимое сочетание любых из четырех модификаторов доступа (§10.3.5), а также модификаторы new (§10.3.4), static (§10.6.2), virtual (§10.6.3), override (§10.6.4), sealed (§10.6.5), abstract (§10.6.6) и extern (§10.6.7).
В отношении использования сочетаний модификаторов объявления событий подчиняются тем же правилам, что и объявления методов (§10.6).
Тип объявления события должен быть типом_делегата (§4.2) с уровнем доступности не меньшим, чем у самого события (§3.5.4).
Объявление события может включать объявления_методов_доступа_событий. Однако если такие объявления отсутствуют, для событий, не являющихся абстрактными или внешними, компилятор автоматически предоставляет их (§10.8.1). Для внешних событий методы доступа предоставляются внешне.
Объявление события, в котором опущены объявления_методов_доступа_событий, определяет одно или несколько событий - по одному для каждого декларатора_переменной. Атрибуты и модификаторы применяются ко всем членам, объявленным с помощью такого объявления_события.
Если объявление_события содержит одновременно модификатор abstract и заключенные в фигурные скобки объявления_методов_доступа_событий, возникает ошибка времени компиляции.
Если объявление события содержит модификатор extern, событие является внешним событием. Поскольку объявления внешних событий не предоставляют фактической реализации, при наличии одновременно модификатора extern и объявлений_методов_доступа_событий возникает ошибка.
Событие может использоваться в качестве левого операнда в операторах «+=» и «-=» (§7.16.3). Эти операторы используются для присоединения к событию обработчика событий или его удаления соответственно. Модификаторы доступа события определяют контексты, в которых такие операции разрешены.
Операторы «+=» и «-=» являются единственно допустимыми операторами для события вне типа, в котором оно объявлено. В связи с этим внешний код может добавлять обработчики к событию и удалять их, однако не может получать или изменять базовый список обработчиков событий.
В операциях вида x += y или x -= y (где для события x выполняется ссылка за пределы типа, который содержит объявление x) результат операции имеет тип void (а не значение x с типом x после присваивания). Это правило не допускает непосредственного просмотра базового делегата события внешним кодом.
В следующем примере показан порядок вложения обработчиков событий в экземпляры класса Button:
public delegate void EventHandler(object sender, EventArgs e);
public class Button: Control
{
public event EventHandler Click;
}
public class LoginDialog: Form
{
Button OkButton;
Button CancelButton;
public LoginDialog() {
OkButton = new Button(...);
OkButton.Click += new EventHandler(OkButtonClick);
CancelButton = new Button(...);
CancelButton.Click += new EventHandler(CancelButtonClick);
}
void OkButtonClick(object sender, EventArgs e) {
// Обрабатывает событие OkButton.Click
}
void CancelButtonClick(object sender, EventArgs e) {
// Обрабатывает событие CancelButton.Click
}
}
В этом примере с помощью конструктора экземпляра LoginDialog создается два экземпляра класса Button и присоединяются обработчики событий для событий Click.
10.8.1 События, подобные полям
В тексте программы в классе или структуре, содержащих объявление события, некоторые события можно использовать как поля. Для такого использования событие не должно быть abstract или extern и не должно явно включать объявления_методов_доступа_к_событиям. Такое событие можно использовать в любом контексте, где разрешено использование поля. Это поле содержит делегат (§15), ссылающийся на список обработчиков событий, добавленных к этому событию. Если обработчики событий не добавлены, поле содержит null.
В примере
public delegate void EventHandler(object sender, EventArgs e);
public class Button: Control
{
public event EventHandler Click;
protected void OnClick(EventArgs e) {
if (Click != null) Click(this, e);
}
public void Reset() {
Click = null;
}
}
Событие Click используется как поле внутри класса Button. Как показано в примере, это поле можно проверять, изменять и использовать в выражениях вызова делегата. Метод OnClick в классе Button "вызывает" событие Click. Понятие вызова события совершенно эквивалентно вызову делегата, представленного событием-так, не существует специальных языковых конструкций для вызова событий. Обратите внимание, что вызову делегата предшествует проверка, что делегат не равен null.
Вне объявления класса Button член Click может использоваться только с левой стороны операторов += и -=, как в
Groupby 1 страница | Groupby 8 страница | Foreach | Continue | Checked и unchecked | Using namespace | Partial. 9 страница | Volatile 1 страница | Volatile 6 страница | Volatile 7 страница |