Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET EventHandlers - Generic or no?

Tags:

Every time I start in deep in a C# project, I end up with lots of events that really just need to pass a single item. I stick with the EventHandler/EventArgs practice, but what I like to do is have something like:

public delegate void EventHandler<T>(object src, EventArgs<T> args);  public class EventArgs<T>: EventArgs {    private T item;    public EventArgs(T item) {     this.item = item;   }    public T Item {     get { return item; }   } } 

Later, I can have my

public event EventHandler<Foo> FooChanged;  public event EventHandler<Bar> BarChanged; 

However, it seems that the standard for .NET is to create a new delegate and EventArgs subclass for each type of event. Is there something wrong with my generic approach?


EDIT: The reason for this post is that I just re-created this in a new project, and wanted to make sure it was ok. Actually, I was re-creating it as I posted. I found that there is a generic EventHandler<TEventArgs>, so you don't need to create the generic delegate, but you still need the generic EventArgs<T> class, because TEventArgs: EventArgs.
Another EDIT: One downside (to me) of the built-in solution is the extra verbosity:
public event EventHandler<EventArgs<Foo>> FooChanged; 

vs.

public event EventHandler<Foo> FooChanged; 

It can be a pain for clients to register for your events though, because the System namespace is imported by default, so they have to manually seek out your namespace, even with a fancy tool like Resharper... Anyone have any ideas pertaining to that?

like image 528
Chris Marasti-Georg Avatar asked Sep 24 '08 19:09

Chris Marasti-Georg


People also ask

Why is EventHandler t a useful generic type?

The advantage of using EventHandler<TEventArgs> is that you do not need to code your own custom delegate if your event generates event data. You simply provide the type of the event data object as the generic parameter.

When would you use an event handler?

Use the EventHandler delegate for all events that don't include event data. Use the EventHandler<TEventArgs> delegate for events that include data about the event. These delegates have no return type value and take two parameters (an object for the source of the event and an object for event data).

Which is the best place to subscribe event handler to an event?

To subscribe to events by using the Visual Studio IDEOn top of the Properties window, click the Events icon. Double-click the event that you want to create, for example the Load event. Visual C# creates an empty event handler method and adds it to your code. Alternatively you can add the code manually in Code view.

Is an event handler a delegate?

The EventHandler delegate is a predefined delegate that specifically represents an event handler method for an event that does not generate data. If your event does generate data, you must use the generic EventHandler<TEventArgs> delegate class.


1 Answers

Delegate of the following form has been added since .NET Framework 2.0

public delegate void EventHandler<TArgs>(object sender, TArgs args) where TArgs : EventArgs 

You approach goes a bit further, since you provide out-of-the-box implementation for EventArgs with single data item, but it lacks several properties of the original idea:

  1. You cannot add more properties to the event data without changing dependent code. You will have to change the delegate signature to provide more data to the event subscriber.
  2. Your data object is generic, but it is also "anonymous", and while reading the code you will have to decipher the "Item" property from usages. It should be named according to the data it provides.
  3. Using generics this way you can't make parallel hierarchy of EventArgs, when you have hierarchy of underlying (item) types. E.g. EventArgs<BaseType> is not base type for EventArgs<DerivedType>, even if BaseType is base for DerivedType.

So, I think it is better to use generic EventHandler<T>, but still have custom EventArgs classes, organized according to the requirements of the data model. With Visual Studio and extensions like ReSharper, it is only a matter of few commands to create new class like that.

like image 159
2 revs Avatar answered Oct 05 '22 08:10

2 revs