Event Design

Events are mechanisms that allow application-specific code to execute when an action occurs. Events happen either before the associated action occurs (pre-events) or after the action occurs (post-events). For example, when a user clicks a button in a window, a post-event is raised allowing application-specific methods to execute. An event-handler delegate is bound to the method to be executed when the system raises an event. The event handler is added to the event so that it is able to invoke its method when the event is raised. Events can have event-specific data (for example, a mouse down event can include data about the screen cursor's location).

The signature of the event-handling method is identical to the signature of the event-handler delegate. The event-handler signature observes the following conventions:

  • The return type is Void.

  • The first parameter is named sender and is of type Object. This is the object that raised the event.

  • The second parameter is named e and is of type EventArgs or a derived class of EventArgs.This is the event-specific data.

  • The method takes exactly two parameters.

For more information about events, see Handling and Raising Events.

Do use the raise terminology for events rather than fire or trigger.

Do use System.EventHandler<T> instead of manually creating new delegates to be used as event handlers.

This guideline mainly applies to new feature areas. If you are expanding the functionality in an area that already uses non-generic event handlers, you can continue to use non-generic event handlers to keep the design consistent.

You cannot comply with this guideline if your library targets versions of the .NET Framework that do not support generics.

Consider using a derived class of System.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 System.EventArgs type directly.

If you define an event that takes an EventArgs instance instead of a derived class that you define, you cannot add data to the event in later versions. For that reason, it is preferable to create an empty derived class of EventArgs. This allows you add data to the event in later versions without introducing breaking changes.

Do use a protected virtual method to raise each event. This is applicable only to non-static events on unsealed classes, not to structures, sealed classes, or static events.

Complying with this guideline allows derived classes to handle a base class event by overriding the protected method. The name of the protected virtual (Overridable in Visual Basic) method should be the same as the event name prefixed with On. For example, the protected virtual method for an event named "TimeChanged" is named "OnTimeChanged".

Important noteImportant Note:

Derived classes that override the protected virtual method are not required to call the base class implementation. The base class must continue to work correctly even if its implementation is not called.

Do use a parameter that is typed as the event argument class to the protected method that raises an event. The parameter should be named e.

The FontDialog class provides the following method, which raises the Apply event:

Protected Overridable Sub OnApply( ByVal e As EventArgs )
protected virtual void OnApply(EventArgs e);

Do not pass null (Nothing in Visual Basic) as the sender parameter when raising a non-static event.

On static events, the sender parameter should be null (Nothing in Visual Basic).

Do not pass null (Nothing in Visual Basic) as the event data parameter when raising an event.

If there is no event data, pass Empty instead of null.

Do be prepared for arbitrary code executing in the event-handling method.

Consider placing the code where the event is raised in a try-catch block to prevent program termination due to unhandled exceptions thrown from the event handlers.

Consider raising events that the end user can cancel. This applies only to pre-events.

If you are designing a cancelable event, use CancelEventArgs instead of EventArgs as the base class for the event data object e.

Portions Copyright 2005 Microsoft Corporation. All rights reserved.

Portions Copyright Addison-Wesley Corporation. All rights reserved.

For more information on design guidelines, see the "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" book by Krzysztof Cwalina and Brad Abrams, published by Addison-Wesley, 2005.

See Also

Concepts

Custom Event Handler Design

Other Resources

Member Design Guidelines

Design Guidelines for Developing Class Libraries