Wednesday, December 03, 2008
It seems that just about every project I work on requires that I write classes that expose events.  Of course this isn't surprising or new.  What has always bothered me was the fact that this tends to generate lots of custom delegates - especially if you have multiple developers working on a project.  Often, the event is simply passing a single data item, and so we end up with ugliness like this, especially when we want the delegate to be strongly typed:

delegate void StringDelegate(object o, string item);
delegate void IntDelegate(object o, int item);
delegate void BoolDelegate(object o, bool item);
delegate void StringListDelegate(object o, List<string> item);

...

public event StringDelegate StringEvent;
public event IntDelegate IntEvent;
public event BoolDelegate BoolEvent;
public event StringListDelegate StringListEvent;


It's ugly, it's a pain in the ass to maintain, and it's just terribly redundant.

Lately I've started using a much simpler pattern heavily leveraging generics.  First, the only declaration outside of the event is a single type:

public class GenericEventArg<T> : EventArgs
{
   public GenericEventArg(T value)
   {
     Value = value;
   }

   public T Value { get; set; }
}

Using this, I can create a strongly-typed event to pass any form of argument like this:

public event EventHandler<GenericEventArg<MyClass>> MyClassEvent;
public event EventHandler<GenericEventArg<List<string>>> StringListEvent;
public event EventHandler<GenericEventArg<int>> IntEvent;

No custom delegate required since we use the EventHandler<> delegate for them all.

12/3/2008 12:28:08 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]  |