Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating EventArgs Using Generics

0.00/5 (No votes)
6 Jan 2008 2  
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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here