Common Type System—Events


Jump to: navigation, search
Visual C# Tutorials
.NET Framework Tutorials

Common Type System

© 2006 Wiley Publishing Inc.

Events

CLR types may contain events. Much like properties, events are more of a convention and pattern than a feature of the CTS itself. As such, they too are marked with the specialname token. Events enable clients to subscribe to get notifications about interesting occurrences having to do with a type. For example, Windows Forms uses events quite extensively to enable programmers to respond to various UI events, such as a button click, the window closing, the user typing a key in a textbox, and so on. They can, of course, also be used for communication associated with your object models.

C# makes it simple to express events. The event keyword is used to declare a member on a class, for example:

using System;
class Foo : IDisposable
{
   public event EventHandler OnInitialized;
   public event EventHandler OnDisposed;
 
   public void Init()
   {
      // Initialize our state...
      EventHandler onInit = OnInitialized;
      if (onInit != null)
         onInit(this, new EventArgs());
   }
 
   public void Dispose()
   {
      // Release our state...
      EventHandler onDisp = OnDisposed;
      if (onDisp != null)
         onDisp(this, new EventArgs());
   }
}

The type Foo exposes two events, OnInitialized and OnDisposed, to which consumers may subscribe. Each is of type EventHandler, which is a delegate type in the System namespace. Delegates are a crucial part of the CTS, discussed later in this chapter. In this example, we accepted the default implementation for subscription and removal of events, although C# also offers a more powerful syntax to write your own implementation. We signal that the events have occurred by calling the delegates represented by our events. If nobody has subscribed, the delegate will be null; thus, we check before trying to make the call (to avoid a NullReferenceException).

Clients may then subscribe to these events:

using (Foo f = new Foo())
{
   f.OnInitialized += delegate { Console.WriteLine("init"); };
   f.OnDisposed += delegate { Console.WriteLine("disposed"); };
   // ...
   f.Init();
   // ...
}

The client here subscribes to the events using C#’s += syntax. Notice that the code used to respond to an event is represented by passing an anonymous delegate. This exposes a form of user extensibility in your APIs.

The representation of events in the IL is not quite as straightforward as C# makes it look. It gets compiled into an add_OnXxx and remove_OnXxx method, each of which accepts an EventHandler instance. The list of event subscriptions is stored inside a Delegate, which offers methods like Combine and Remove to participate with events.


Previous_Page_.gif Next_Page_.gif





Personal tools