Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How Events Work Under the Surface

0.00/5 (No votes)
1 Jan 2007 1  
Shows what goes on behind the "magic" that the compiler does when you declare a simple event member in a class.

Introduction

This article aims to show you what goes on behind the "magic" that the compiler does when you declare a simple event member in a class. It is meant as a beginner article to answer a frequently-asked question, so please don't vote it down just because it is very basic.


Multicast Delegates: The Foundation of Events

A pre-requisite to understanding how events work under the surface is to understand how multicast delegates work. A multicast delegate is a combined delegate that is made up of multiple single delegates joined together into a single object. The delegate can be called the same way you would call a normal delegate that only represents a reference to one method, but it will invoke all the methods it represents each time it is called. Let's see this in action. Say we have 2 methods in a class, named MyMethod1 and MyMethod2:

public void MyMethod1()
{
    Console.WriteLine("Method 1");
}

public void MyMethod2()
{
    Console.WriteLine("Method 2");
}

The methods have no parameters or return value so we create an "empty" delegate signature with no return value or arguments:

public delegate void EmptyDelegate();

Now, we want to call both delegates at once, so we use Delegate.Combine() to create a combined delegate, with references to both methods:

//Create a new multicast delegate that contains references to 

//both methods at once.

EmptyDelegate multicast=(EmptyDelegate)Delegate.Combine(
    new EmptyDelegate(MyMethod1),
    new EmptyDelegate(MyMethod2)
    );
//Call the new multicast delegate.

multicast();

When the multicast delegate is called, both methods will be executed in the order they were combined in, so the console output will be:

Method 1
Method 2

How Events Are Implemented

Now that we've seen how multi-cast delegates work, let's look at how events make use of them. An event is a wrapper over a multi-cast delegate field, that only allows outside objects to add and remove handlers. To better understand how this works, let's look at the more verbose way to declare an event.

First, define a field whose data type is a delegate type (in this case EventHandler):

private EventHandler myEventHandlers;

This is a simple field that can hold a multi-cast delegate containing references to all the handlers that are listening to the event.

Next we define a special event declaration, that is much like a property in its syntax, but it is declared with the event keyword, instead of get and set accessors, to get and set a property value, it has add and remove accessors, to add and remove handlers from the event. Notice the use of Delegate.Combine() to combine delegates, and Delegate.Remove() to remove a single delegate from a multi-cast delegate.

//Event declaration - similar in syntax to a property declaration

public event EventHandler MyEvent
{
    add
    {
        //Combine the multi-cast delegate that has the existing handlers

        //with the new handler delegate, to make a new multi-cast delegate 

        //that includes both the existing handlers and the new handler.

        myEventHandlers = (EventHandler)
            Delegate.Combine(myEventHandlers, value);
    }
    remove
    {
        //Create a new multi-cast delegate that contains all 

        //the existing handlers,

        //except for the one that's being removed.

        myEventHandlers = (EventHandler)
            Delegate.Remove(myEventHandlers, value);
    }
}

This will result in the same generated code as the normal type of declaration will:

public event EventHandler MyEvent;

So there you go: underneath, an event is a multi-cast delegate in a private field (member variable), and then a special public accessor that only allows adding and removing handlers from the multi-cast delegate.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here