Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
События, как и делегаты, представляют собой механизм поздней привязки. На самом деле события основаны на поддержке языка делегатов.
События — это способ уведомления объекта всем заинтересованным компонентам в системе о том, что что-то произошло. Любой другой компонент может подписаться на событие и получать уведомления при возникновении события.
Возможно, вы использовали события в некоторых программах. Многие графические системы имеют модель событий для отчета о взаимодействии с пользователем. Эти события будут сообщать о перемещении мыши, нажатия кнопки и аналогичных взаимодействиях. Это один из наиболее распространенных, но не единственный сценарий, в котором используются события.
Вы можете определить события, которые должны быть вызваны для ваших классов. Одним из важных соображений при работе с событиями является то, что для определенного события может не быть зарегистрирован какой-либо объект. Необходимо написать код, чтобы он не вызывал события, если прослушиватели не настроены.
Подписка на событие также создает связь между двумя объектами (источником событий и приемником событий). Необходимо убедиться, что приемник событий отменяет подписку с источника событий, когда в событиях больше нет заинтересованности.
Цели разработки для поддержки событий
Разработка языка для событий нацелена на следующие цели:
- Включите минимальное взаимодействие между источником событий и приемником событий. Эти два компонента могут быть написаны различными организациями и даже могут быть обновлены по разным расписаниям.
- Подписаться на событие и отписаться от него должно быть просто.
- Источники событий должны поддерживать несколько подписчиков событий. Оно также должно поддерживать наличие отсутствия подключенных подписчиков событий.
Вы можете увидеть, что цели у мероприятий аналогичны целям делегатов. Поэтому поддержка языка событий основана на поддержке языка делегатов.
Поддержка языков для событий
Синтаксис для определения событий и подписки или отмены подписки на события является расширением синтаксиса для делегатов.
Ключевое слово event
используется для определения события:
public event EventHandler<FileFoundArgs>? FileFound;
Тип события (EventHandler<FileListArgs>
в этом примере) должен быть делегатным типом. Существуют соглашения, которые следует следовать при объявлении события. Как правило, тип делегата события имеет возвращаемое значение void. Названия событий должны быть глаголом или глагольной фразой. Используйте прошлое время, когда событие сообщает о том, что произошло. Используйте глагол в настоящем времени (например, Closing
), чтобы сообщить о том, что вот-вот произойдет. Часто использование настоящего времени указывает на то, что ваш класс поддерживает определенное поведение настройки. Одним из наиболее распространенных сценариев является поддержка отмены. Например, событие Closing
может включать аргумент, указывающий, следует ли продолжить операцию закрытия или нет. Некоторые сценарии позволяют вызывающим объектам изменять поведение путем обновления свойств аргументов события. Вы можете вызвать событие, чтобы указать предлагаемое следующее действие, которое будет предпринять алгоритм. Обработчик событий может потребовать другого действия, изменив свойства аргумента события.
Если вы хотите вызвать событие, вызовите обработчики событий с помощью синтаксиса вызова делегата:
FileFound?.Invoke(this, new FileFoundArgs(file));
Как обсуждалось в разделе о делегатах , оператор ?.
упрощает обеспечение того, что вы не попытаетесь вызвать событие, когда нет подписчиков на это событие.
Вы подписываетесь на событие, используя оператор +=
:
var fileLister = new FileSearcher();
int filesFound = 0;
EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>
{
Console.WriteLine(eventArgs.FoundFile);
filesFound++;
};
fileLister.FileFound += onFileFound;
Метод обработчика обычно имеет префикс On, за которым следует имя события, как показано в предыдущем коде.
Отмена подписки с помощью оператора -=
:
fileLister.FileFound -= onFileFound;
Важно объявить локальную переменную для выражения, представляющего обработчик событий. Это гарантирует, что отмена подписки приводит к удалению обработчика. Если вместо этого вы использовали тело лямбда-выражения, вы пытаетесь удалить обработчик, который никогда не был присоединен, поэтому это не оказывает никакого эффекта.
В следующей статье вы узнаете больше о типичных шаблонах событий и различных вариантах в этом примере.