Is there a special association between the EventArgs class and the event keyword?

355 Views Asked by At

In all the .NET book I've read the guide line for implementing events explains that you need to subclass EventArgs and use EventHandler. I looked up more info on http://msdn.microsoft.com/en-us/library/ms229011.aspx, and it says "Do use System.EventHandler instead of manually creating new delegates to be used as event handlers." I understand that there are important reasons to use EventArgs, but my question is not "Should I do it this way?", but "Can I do it this way?".

Is there any reason that I can't use a generic delegate instead of an EventHandler with my events? For example, if I want a strongly-typed sender (anyone else get annoyed by that object sender?) .

To explain what I mean better, is there any reason the following won't work?

public class IoC
{
    public AbstractFactory GetAbstractFactory()
    {
        var factory = new AbstractFactory();
        factory.CreateObject += ()=>new object();
        return factory;
    }
}
public class AbstractFactory
{
    public event Func<object> CreateObject;

    private object OnObjectCreated()
    {
        if(CreateObject == null)
        {
            throw new Exception("Not injected.");
        }
        return CreateObject();
    }


    private object _injectedObject;
    public object InjectedObject
    {
        get
        {
            if(_injectedObject == null)
            {
                _injectedObject = OnObjectCreated();
            }
            return _injectedObject;
        }
    }
}
3

There are 3 best solutions below

0
On BEST ANSWER

It's just convention, and no requirement of the language. You can use any delegate type as an event.

The standard EventHandler<T> signature has a few advantages though:

  1. You can extend the EventArgs parameter. This wouldn't work if you had one parameter for each thing you want to pass into the eventhandler.
  2. An EventHandler which accepts the EventArgs base-class can subscribe to any event following the convention
  3. You can add Extension methods to EventHandler<T> which appear on all events.
  4. Return type is void. Other return types don't make much sense as eventhandlers.
  5. You're following the convention. Following the convention is usually a good idea, unless you have compelling arguments not to.
0
On

All of the documentation from Microsoft is about the design of the base class libraries and/or general framework design guidelines. You can use whatever pattern you want.

That said, if people will be consuming your code it will be more familiar to them if you follow the patterns that Microsoft uses.

1
On

As far as I know, EventHandler and EventArgs are best practices, but there is nothing to to stop you from using any arbitrary delegate in an event declaration. The event keyword gives you the special functionality of being able to += and -= delegates to the event slot, as opposed to simply having a field or property of the delegate type, which will only accept a single delegate (unless you compose multiple delegates yourself).

Caveat: I'm unsure what happens to delegates with return values in an event slot. My guess is return values are discarded, since multiple delegates with return values assigned to the event would be hard to handle. This would require some experimentation though.