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