2

I try to stick as much as possible to the Framework Design Guidelines even when designing class libraries intended only for internal use.

To a certain degree, it makes my life easier as I use Code Analysis to automate checking for places I may not be using best-practices.

But here's a case where I feel very compeled to just ignore the recommendations.

Since the EventArgs constraint was removed from EventHandler in .NET 4, why would anyone want to use a class derived from EventArgs (as prescribed at https://msdn.microsoft.com/en-us/library/ms229011(v=vs.110).aspx) nowadays instead of using the desired data type directly and avoiding the cost of allocating another object and embeding the desired data in it?

For instance, having to write the following:

public class ExceptionEventArgs : EventArgs
{
    private readonly Exception _exception;

    public ExceptionEventArgs(Exception exception)
    {
        _exception = exception;
    }

    public Exception Exception
    {
        get
        {
            return _exception;
        }
    }
}

public event EventHandler<ExceptionEventArgs>;

is much more verbose as costs an extra allocation instead of:

public event EventHandler<Exception>;

I even created a generic EventArgs for using on another class a couple of weeks ago, but I feel silly to do so just for the sake of sticking to the guidelines.

public class EventArgs<T> : EventArgs
{
    private readonly T _data;

    public EventArgs(T data)
    {
        _data = data;
    }

    public T Data
    {
        get
        {
            return _data;
        }
    }
}

So, are there any cons for using

EventHandler<NotAnEventArgsDerivedClass>

for classes intended for internal* use only?

*By that I really mean, for use on a product comprised of several assemblies - all of which are intended for use exclusively by the product itself.

Nejc Galof
  • 2,538
  • 3
  • 31
  • 70
Alfred Myers
  • 6,384
  • 1
  • 40
  • 68

1 Answers1

1

It's preferable not to inherit from EventArgs. There are no cons to using

EventHandler<NotAnEventArgsDerivedClass>

but it still makes the assumption that you want to pass sender as an object when it may or may not make sense to pass sender at all.

Use of EventArgs is the only case I can think of where it's common to inherit from a class because of convention when we don't actually need the class we're inheriting from. Similarly the standard Handler(object sender, EventArgs e) delegate is the only case I know where it's common to design a method signature based on convention and not on the requirements for that specific method. It encourages us to pass an untyped parameter when it may or may not even make sense for us to pass the sender at all. It results in methods where we ignore arguments, don't trust the values of arguments, and cast objects to more specific types because we "just know" what they really are.

As in any other design we should create the methods we need and pass the parameters we need. There may be cases where conventions are useful but this isn't one of them.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62