Разработка событий

Примечание.

Это содержимое перепечатывается разрешением Pearson Education, Inc. из руководства по проектированию платформы: соглашения, идиомы и шаблоны для повторно используемых библиотек .NET, 2-го выпуска. Этот выпуск был опубликован в 2008 году, и книга с тех пор была полностью пересмотрена в третьем выпуске. Некоторые сведения на этой странице могут быть устаревшими.

События — это наиболее часто используемая форма обратных вызовов (конструкции, позволяющие платформе вызывать пользовательский код). Другие механизмы обратного вызова включают элементы, принимающие делегаты, виртуальные члены и подключаемые модули на основе интерфейса. Данные из исследований удобства использования показывают, что большинство разработчиков более комфортно используют события, чем используют другие механизмы обратного вызова. События хорошо интегрируются с Visual Studio и многими языками.

Важно отметить, что существует две группы событий: события, вызванные до изменений состояния системы (события до операции), и события, вызванные после изменений состояния (события после операции). Примером события до операции может быть Form.Closing, которое вызывается перед закрытием формы. Примером события после операции может быть Form.Closed, которое вызывается после закрытия формы.

✔️ Для событий СЛЕДУЕТ использовать термин "вызывать", а не "инициировать" или "активировать".

✔️ Чтобы вручную не создавать делегаты для использования в качестве обработчиков событий, СЛЕДУЕТ использовать System.EventHandler<TEventArgs>.

✔️ Рассмотрите возможность использования подкласса EventArgs в качестве аргумента события, если вы не уверены, что событию никогда не нужно будет передавать какие-либо данные в метод обработки событий. В этом случае можно использовать тип EventArgs напрямую.

Если вы подаете API с помощью EventArgs напрямую, вы никогда не сможете добавить данные, которые будут передаваться вместе с событием, не нарушая совместимости. Если используется подкласс, при необходимости вы сможете добавлять в него свойства (даже если изначально он полностью пустой).

✔️ СЛЕДУЕТ использовать защищенный виртуальный метод для вызова каждого события. Это применимо только к нестатическим событиям для незапечатанных классов, а не к структурам, запечатанным классам или статическим событиям.

Цель метода — предоставить для производного класса способ обработать событие с помощью переопределения. Переопределение является более гибким, быстрым и естественным способом для обработки событий базового класса в производных классах. По соглашению имя метода должно начинаться с префикса On, после него должно следовать имя события.

Производный класс может не вызывать базовую реализацию метода в его переопределении. Будьте готовы к этому: не включайте какую-либо обработку в метод, который требуется для правильной работы базового класса.

✔️ СЛЕДУЕТ️ принять один параметр для защищенного метода, который порождает событие.

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

❌ НЕ передавайте значение NULL в качестве отправителя при вызове нестатического события.

✔️ ПЕРЕДАВАЙТЕ значение NULL в качестве отправителя при вызове статического события.

❌ НЕ передавайте значение NULL в качестве параметра данных события при вызове события.

Следует передать EventArgs.Empty, если вы не хотите передавать какие-либо данные в метод обработки событий. Разработчики предполагают, что этот параметр не должен иметь значение NULL.

✔️ РАССМОТРИТЕ возможность вызова событий, которые может отменить пользователь. Это применяется только к событиям до операции.

Чтобы разрешить пользователю отменять события, используйте в качестве аргумента события System.ComponentModel.CancelEventArgs или его подкласс.

Разработка пользовательского обработчика событий

В некоторых случая нельзя использовать EventHandler<T>, например, если платформа должна работать с более ранними версиями среды CLR, которые не поддерживали универсальные шаблоны. В таких случаях может потребоваться спроектировать и разработать пользовательский делегат обработчика событий.

✔️ СЛЕДУЕТ️ использовать тип возвращаемого значения void для обработчиков событий.

Обработчик событий может вызывать несколько методов обработки событий, возможно, для нескольких объектов. Если бы методам обработки событий можно было возвращать значение, то для каждого вызова события было бы несколько возвращаемых значений.

✔ В качества типа первого параметра обработчика событий СЛЕДУЕТ️ использовать object. Присвойте ему имя sender.

✔ В качества типа второго параметра обработчика событий СЛЕДУЕТ️ использовать System.EventArgs. Присвойте ему имя e.

❌ В обработчиках событий НЕ должно быть больше двух параметров.

Фрагменты: © Корпорация Майкрософт (Microsoft Corporation), 2005, 2009. Все права защищены.

Перепечатано с разрешения Pearson Education, Inc. из книги Инфраструктура программных проектов. Соглашения, идиомы и шаблоны для многократно используемых библиотек .NET (2-е издание), авторы: Кржиштоф Цвалина (Krzysztof Cwalina) и Брэд Абрамс (Brad Abrams). Книга опубликована 22 октября 2008 г. издательством Addison-Wesley Professional в рамках серии, посвященной разработке для Microsoft Windows.

См. также