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

События — это наиболее часто используемая форма обратных вызовов (конструкций, позволяющая платформе вызывать пользовательский код).Events are the most commonly used form of callbacks (constructs that allow the framework to call into user code). Другие механизмы обратного вызова включают члены, принимающие делегаты, виртуальные члены и подключаемые модули на основе интерфейсов. данные из исследований удобства использования указывают на то, что большинство разработчиков более удобно использовать события, чем они используют другие механизмы обратного вызова. .Other callback mechanisms include members taking delegates, virtual members, and interface-based plug-ins. Data from usability studies indicate that the majority of developers are more comfortable using events than they are using the other callback mechanisms. События хорошо интегрируются с Visual Studio и многими языками.Events are nicely integrated with Visual Studio and many languages.

Важно отметить, что существует две группы событий: события, вызванные до изменения состояния системы, называемые событиями pre-Events, и события, возникающие после изменения состояния, называемые событиями после.It is important to note that there are two groups of events: events raised before a state of the system changes, called pre-events, and events raised after a state changes, called post-events. Примером предварительного события может быть Form.Closing, который вызывается перед закрытием формы.An example of a pre-event would be Form.Closing, which is raised before a form is closed. Примером события, поступающего после закрытия формы, может быть Form.Closed.An example of a post-event would be Form.Closed, which is raised after a form is closed.

✔️ использовать термин «raise» для событий, а не «пожар» или «Trigger».✔️ DO use the term "raise" for events rather than "fire" or "trigger."

✔️ использовать System.EventHandler<TEventArgs> вместо того, чтобы вручную создавать новые делегаты для использования в качестве обработчиков событий.✔️ DO use System.EventHandler<TEventArgs> instead of manually creating new delegates to be used as event handlers.

✔️ Рассмотрите возможность использования подкласса EventArgs в качестве аргумента события, если только вы не уверены, что событие никогда не будет передавать какие-либо данные в метод обработки событий. в этом случае можно использовать тип EventArgs напрямую.✔️ CONSIDER using a subclass of EventArgs as the event argument, unless you are absolutely sure the event will never need to carry any data to the event handling method, in which case you can use the EventArgs type directly.

Если вы подаете API с помощью EventArgs напрямую, вы никогда не сможете добавлять данные, которые будут перенесены с событием без нарушения совместимости.If you ship an API using EventArgs directly, you will never be able to add any data to be carried with the event without breaking compatibility. Если вы используете подкласс, даже если изначально он полностью пуст, вы сможете добавлять свойства в подкласс при необходимости.If you use a subclass, even if initially completely empty, you will be able to add properties to the subclass when needed.

для вызова каждого события ✔️ использовать защищенный виртуальный метод.✔️ DO use a protected virtual method to raise each event. Это применимо только к нестатическим событиям в незапечатанных классах, а не к структурам, запечатанным классам или статическим событиям.This is only applicable to nonstatic events on unsealed classes, not to structs, sealed classes, or static events.

Цель метода — предоставить способ для производного класса, обрабатывающий событие с помощью переопределения.The purpose of the method is to provide a way for a derived class to handle the event using an override. Переопределение является более гибким, быстрым и естественным способом управления событиями базового класса в производных классах.Overriding is a more flexible, faster, and more natural way to handle base class events in derived classes. По соглашению имя метода должно начинаться с "on" и состоять из имени события.By convention, the name of the method should start with "On" and be followed with the name of the event.

Производный класс может не вызывать базовую реализацию метода в его переопределении.The derived class can choose not to call the base implementation of the method in its override. Будьте готовы к этому, не включая обработку в методе, который требуется для правильной работы базового класса.Be prepared for this by not including any processing in the method that is required for the base class to work correctly.

✔️ принимать один параметр для защищенного метода, который вызывает событие.✔️ DO take one parameter to the protected method that raises an event.

Параметр должен иметь имя e и быть типизированным в качестве класса аргумента события.The parameter should be named e and should be typed as the event argument class.

❌ не передавать NULL в качестве отправителя при вызове нестатического события.❌ DO NOT pass null as the sender when raising a nonstatic event.

✔️ передать NULL в качестве отправителя при вызове статического события.✔️ DO pass null as the sender when raising a static event.

При вызове события ❌ не передавать значение NULL в качестве параметра данных события.❌ DO NOT pass null as the event data parameter when raising an event.

Следует передавать EventArgs.Empty, если вы не хотите передавать какие бы то ни было данные в метод обработки событий.You should pass EventArgs.Empty if you don’t want to pass any data to the event handling method. Разработчики предполагают, что этот параметр не должен иметь значение null.Developers expect this parameter not to be null.

✔️ Рассмотрите возможность вызова событий, которые может отменить конечный пользователь.✔️ CONSIDER raising events that the end user can cancel. Это относится только к предварительным событиям.This only applies to pre-events.

Используйте System.ComponentModel.CancelEventArgs или его подкласс в качестве аргумента события, чтобы разрешить конечному пользователю отменять события.Use System.ComponentModel.CancelEventArgs or its subclass as the event argument to allow the end user to cancel events.

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

Существуют случаи, в которых EventHandler<T> нельзя использовать, например, если платформа должна работать с более ранними версиями среды CLR, которые не поддерживали универсальные шаблоны.There are cases in which EventHandler<T> cannot be used, such as when the framework needs to work with earlier versions of the CLR, which did not support Generics. В таких случаях может потребоваться разработать и разработать пользовательский делегат обработчика событий.In such cases, you might need to design and develop a custom event handler delegate.

✔️ использовать тип возвращаемого значения void для обработчиков событий.✔️ DO use a return type of void for event handlers.

Обработчик событий может вызывать несколько методов обработки событий, возможно, для нескольких объектов.An event handler can invoke multiple event handling methods, possibly on multiple objects. Если методы обработки событий позволяли возвращать значение, то для каждого вызова события было бы несколько возвращаемых значений.If event handling methods were allowed to return a value, there would be multiple return values for each event invocation.

✔️ использовать object как тип первого параметра обработчика событий и вызвать его sender.✔️ DO use object as the type of the first parameter of the event handler, and call it sender.

✔️ использовать System.EventArgs или его подкласс в качестве типа второго параметра обработчика событий и вызвать его e.✔️ DO use System.EventArgs or its subclass as the type of the second parameter of the event handler, and call it e.

❌ не имеют более двух параметров в обработчиках событий.❌ DO NOT have more than two parameters on event handlers.

Части © 2005, 2009 Корпорация Майкрософт. Все права защищены.Portions © 2005, 2009 Microsoft Corporation. All rights reserved.

Перепечатано с разрешения Pearson Education, Inc. из книги Инфраструктура программных проектов. Соглашения, идиомы и шаблоны для многократно используемых библиотек .NET (2-е издание), авторы: Кржиштоф Цвалина (Krzysztof Cwalina) и Брэд Абрамс (Brad Abrams). Книга опубликована 22 октября 2008 г. издательством Addison-Wesley Professional в рамках серии, посвященной разработке для Microsoft Windows.Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by Addison-Wesley Professional as part of the Microsoft Windows Development Series.

См. также разделSee also