Events and Delegates

An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as a mouse click, or it could be triggered by some other program logic. The object that raises (triggers) the event is called the event sender. The object that captures the event and responds to it is called the event receiver.

In event communication, the event sender class does not know which object or method will receive (handle) the events it raises. What is needed is an intermediary (or pointer-like mechanism) between the source and the receiver. The .NET Framework defines a special type (Delegate) that provides the functionality of a function pointer.

A delegate is a class that can hold a reference to a method. Unlike other classes, a delegate class has a signature, and it can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. While delegates have other uses, the discussion here focuses on the event handling functionality of delegates. The following example shows an event delegate declaration.

// AlarmEventHandler is the delegate for the Alarm event.
// AlarmEventArgs is the class that holds event data for the alarm event.
// It derives from the base class for event data, EventArgs.
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
[Visual Basic]
' AlarmEventHandler is the delegate for the Alarm event.
' AlarmEventArgs is the class that holds event data for the alarm event.
' It derives from the base class for event data, EventArgs.
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)

The syntax is similar to that of a method declaration; however, the delegate keyword informs the compiler that AlarmEventHandler is a delegate type.

By convention, event delegates in the .NET Framework have two parameters, the source that raised the event and the data for the event.

Note   A delegate declaration is sufficient to define a delegate class. The declaration supplies the signature of the delegate, and the common language runtime provides the implementation.

An instance of the AlarmEventHandler delegate can bind to any method that matches its signature, such as the AlarmRang method of the WakeMeUp class shown in the following example.

public class WakeMeUp 
{
// AlarmRang has the same signature as AlarmEventHandler.
public void AlarmRang(object sender, AlarmEventArgs e){...};
...
}
[Visual Basic]
Public Class WakeMeUp
   ' AlarmRang has the same signature as AlarmEventHandler.
   Public Sub AlarmRang(sender As Object, e As AlarmEventArgs)
      ...
   End Sub
   ...
End Class

To connect (wire) AlarmRang to an Alarm event:

  1. Create an instance of the AlarmEventHandler delegate that takes a reference to the AlarmRang method of the WakeMeUp instance in its constructor, as shown in the following example.

    // Create an instance of WakeMeUp.
    //
    WakeMeUp w = new WakeMeUp();
    
    // Instantiate the event delegate.
    // The C# compiler provides a constructor for event handlers that takes 
    // one parameter, the reference to the method that performs the 
    // event handling logic. The two-parameter constructor for EventHandler
    // provided in the class library is intended for developers of
    // compilers and other tools.
    //
    AlarmEventHandler alhandler = new AlarmEventHandler(w.AlarmRang);
    [Visual Basic]
    ' Create an instance of WakeMeUp.
    '
    Dim w As New WakeMeUp()
    
    ' Instantiate the event delegate.
    Dim alhandler As AlarmEventHandler = AddressOf w.AlarmRang
    

    Now, whenever alhandler is called, it in turn calls the AlarmRang method of the WakeMeUp instance.

  2. Register the alhandler delegate with the Alarm event. For details and a complete sample, see Event Sample.

Custom event delegates are needed only when an event generates event data. Many events, including some user-interface events such as mouse clicks, do not generate event data. In such situations, the event delegate provided in the class library for the no-data event, System.EventHandler, is adequate. Its declaration follows.

// The base class for event data, EventArgs, does not have
// any data and hence can be used as the event data type for events
// that do not generate data.
//
delegate void EventHandler(object sender, EventArgs e);
[Visual Basic]
' The base class for event data, EventArgs, does not have
' any data and hence can be used as the event data type for events
' that do not generate data.
'
Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)

Event delegates are multicast, which means that they can hold references to more than one event handling method. For details, see Delegate. Delegates allow for flexibility and fine-grain control in event handling. A delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event handlers for the event.

For details on using delegates to provide event functionality in your component or control, seeRaising an Event.

For an overview of consuming events in your applications, see Consuming Events.

See Also

Consuming Events | Raising an Event | Event Sample