65.9K
CodeProject is changing. Read more.
Home

Creating EventArgs Using Generics

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.89/5 (7 votes)

Jan 4, 2008

CPOL

1 min read

viewsIcon

55211

downloadIcon

229

Save Time using Generics creating EventArgs

Introduction

This article describes how to create a generics based EventArgs class.

Background

I have been working on a large project that has required me to write a ton of event args classes just to pass an object of one type or another in the event.

.NET already contains a generic EventHandler Delegate.

 public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e); 

But TEventArgs must derive from EventArgs.
If you want an event that contains an int, you code like the following:

   public class EventArgs_int : EventArgs
    {
        public int Target;
        public EventArgs_int(int i)
        {
            Target = i;
        }
    }

Next, if you want an event that contains a string, you would need:

  public class EventArgs_string : EventArgs
    {
        public string Target;
        public EventArgs_string(string s)
        {
            Target = s;
        }
    }

You need a different class that derives from the EventArgs class for each type of object you want to pass unless you create one that passes an object like:

   public class EventArgs_object : EventArgs
    {
        public object Target;
        public EventArgs_object(object o)
        {
            Target = o;
        }
    }

This class works, but you do not get intellisense and need to cast objects to the proper type. After writing 20 or so different classes, I came up with the idea of using generics instead.

Using the Code

Create a class that derives from EventArgs with a generic type:

public class EventArgs_Generic<t>: EventArgs
{
    public EventArgs_Generic(t Target)
    {
        _TargetObject = Target;
    }
    private t _TargetObject;
    public t TargetObject
    {
        get
        {
            return _TargetObject;
        }
        set
        {
            _TargetObject = value;
        }
    }
}

Now, let's create a simple class to pass in the event:

   class SimpleObject
    {
        public SimpleObject()
        {
        }
        private int _Value;
        public int Value
        {
            get { return _Value; }
            set { _Value = value; }
        }

        private string _Name;
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
    }

Next, we create an event handler using this class we just created (SimpleObject):

public event EventHandler<EventArgs_Generic<SimpleObject>> SimpleObjectAdded;

To receive the event, you create code like this:

    _Processor.SimpleObjectAdded += new EventHandler<EventArgs_Generic<SimpleObject>>
                    (_Processor_SimpleObjectAdded);

    void _Processor_SimpleObjectAdded(object sender, EventArgs_Generic<SimpleObject> e)
    {
        Console.WriteLine("New Object Name:{0} value: {1}",
                e.TargetObject.Name, e.TargetObject.Value);

        dataGridView1.DataSource = null;
        dataGridView1.DataSource = _Processor.SimpleObjects;
    }

How cool is that! Complete type safety (and type ahead) without creating a different class for each type you want to pass in an Event Argument.

I like it a lot. Hope you do too!

History

  • 4th January, 2008: Initial post
  • 6th January, 2008: Article updated to make intent more clear