One more thing to love about .NET generics: events with custom event args

Lists are a killer app for generics in .NET 2.0 but one of my favourite uses that gets less attention is declaring event handlers without having to create a custom delegeate.

Imagine a situation where you want to pass a piece of custom information to the event handler so it can decide whether to cancel the event. This means you’ll need to declare your own event argument class:

public class MyEventArgs : CancelEventArgs  {
    public MyEventArgs(string informationalProperty)
    {
        this._informationalProperty = informationalProperty;
    }
    private string _informationalProperty;
    public string InformationalProperty
    {
        get { return _informationalProperty; }
    }
}

The pre .NET 2.0 solution

In the old days this would have meant that you would have needed to declare a delegate for your event that had the right signature for the custom event type:

public delegate void MyEventHandler(object sender, MyEventArgs e);
public event MyEventHandler MyEvent;

And then the calling code would have to know about the delegate when it used the event. It’d be one more thing you’d have to have in your public API (one more thing you’d have to write a triple slash comment for):

ClassWithEventDelegate d = new ClassWithEventDelegate();
d.MyEvent += new ClassWithEventDelegate.MyEventHandler(HandleEvent);
d.SomethingThatTriggersEvent();

Shiny new generics solution

.NET 2.0 has a new version of the standard System.EventHandler delegate that takes the name of any class that inherits from System.EventArgs. This means that when you create your event you don’t have to declare a delegate just to have custom event arguments. Now my event declaration is just one line:

public event EventHandler MyEvent;

And the only thing that the code that uses the event needs to know about is the custom event arguments class:

ClassWithEventDelegate d = new ClassWithEventDelegate();
d.MyEvent += new ClassWithEventDelegate.MyEventHandler(HandleEvent);
d.SomethingThatTriggersEvent();

This is just a little tiny saving really but I fell quite in love with it when I was documenting a project with lots of public events last year because it meant each event had one less thing in the API docs (it was the same time I fell in love with the internal keyword). It’s a nice bit of syntactic sugar and I think putting a bit of syntactic sugar in the right place is an important part of what building a really useful language is about. :)

You can download the entire code example if you’d like to have a play with it and see how it works.

Posted on 26 Apr 08 by Helen Emerson (last updated on 26 Apr 08).
Filed under .NET