Reader Level:
ARTICLE

Custom Generic EventArgs

Posted by Matthew Cochran Articles | Coding Best Practices May 14, 2007
Before .NET 2.0, I found myself frequently creating custom EventArgs classes just to return a value from an event and would end of with a lot of extra classes bloating my code base that all basically had the same purpose.
  • 0
  • 0
  • 77908
Download Files:
 

Part I. Core Classes

In order to harness the awesome power of generics with our events, we just need a few lines of code creating a class that inherits from EventArgs that will transport a value of some type:

   public classEventArgs<T> :EventArgs
    {
        public EventArgs(T value)
        {
            m_value = value;
        }

       private T m_value;

       public T Value
        {
            get { return m_value; }
        }
    }

Now we can create an event that returns any type of object and have only one class to maintin.

Sometimes (but not often), we'll have a situation where we need two return values from an event and so we can derive from EventArgs<T>and add another value.

   public classEventArgs<T, U> :EventArgs<T>
    {

       public EventArgs(T value, U value2)
            : base(value)
        {
            m_value2 = value2;
        }

       private U m_value2;

       public U Value2
        {
            get { return m_value2; }
        }
    }

I have a hard time imagining a situation where we would need three return values, but I put an EventArgs<T, U, V>  class in the sample code just in case following the above pattern.

Part II. Implementation

The implementation takes a bit getting used to, expecially if you're not yet used to looking at generics, because we'll have nested generic types, but after a while it will grow on you.

In our event declaration, we'll specify the type of object returned.

privateevent EventHandler<EventArgs<Double>> m_doubleEvent

When we fire off the event, we'll just pass the return value using the constructor we created earlier in Part I.

if (null != m_doubleEvent)
   m_doubleEvent(this,new EventArgs<Double>(9876.5432));

Part III. An Example

I have a couple of buddies in NewJersey who like fishing and have inspired my sample code. I'm just going to give you an overview of how the sample code works so you'll have to download the project code for this article to see it all work.

We have three classes: Fisherman, DirtyLake, and Fish.  TheDirtyLake contains a bunch of stuff floating around and will randomly fire an event when fished in using a "GetSomething()" method.

privateevent EventHandler<EventArgs<String,Double>> m_stringAndDoubleCaught;
privateevent EventHandler<EventArgs<Double>> m_doubleCaught;
privateevent EventHandler<EventArgs<Guid,int, string>> m_guidAndStringAndIntCaught;
privateevent EventHandler<EventArgs<Fish>> m_fishCaught;

The Fisherman class listens to all these events so when he casts his line in the lake and calls GetSomething(), the event is fired off and he receives an event notification.  To do all of this with custom non-generic event args would have required substantially more code.  Download the source code and check it out if you would like to see the whole thing from beginning to end.

Part IV. Wrap up

This technique can be used with web pages, win forms, or anywhere else we may have events (including fishing in dirty lakes).  I hope you found this article useful and it can help you simplify and reduce the amount of code needed to make you apps work.

Until next time,

Happy Coding

COMMENT USING

Trending up