0

Is using a generic DataEventArgs<TData> class, rather than declaring and using a custom EventArgs inherited class, in an event declaration, a violation of the .Net Event "pattern" convention? Or considered bad practice in some circumstances?

(The naming convention of naming the event args is to use the event name and append the postfix "EventArgs". Using DataEventArgs<TData> omits the event name, although it shows you the type of the data transmitted.)

You could perhaps argue that the generic DataEventArgs class is kind of closed for extensions, such as adding another property, unless you can modify the class that you use for TData.


Longer explanation:

When declaring a standard delegate event that includes some data I understand that the standard event "pattern" convention is to declare it using the generic EventHandler delegate thusly:

public event EventHandler<SomethingHappendEventArgs> SomethingHappend;

Where the specific SomethingHappendEventArgs is declared something along the lines of

public class SomethingHappendEventArgs : EventArgs
{
    public SomeDataType Value { get; private set; }
    public SomethingHappendEventArgs(SomeDataType data)
    {
        this.Value = data;
    }
}

When googling around I noticed that there are several Microsoft namespaces that supplies a generic DataEventArgs class, (including Microsoft.Practices.Prism.Events). However I could nowhere find any recommendation or convention indication on when to use that instead of a customized event data class such as SomethingHappendEventArgs or vice versa.

So, provided that there is one piece of data that I want to include in the event data, are there any reasons that I should use customized event data classes, like SomethingHappendEventArgs , rather than declaring events like this?

public event EventHandler<DataEventArgs<SomeDataType>> SomethingHappend;

where the generic DataEventArgs could be declared something like this:

public class DataEventArgs<TData> : EventArgs
{
    public TData Value { get; private set; }
    public DataEventArgs(TData value)
    {
        this.Value = value;
    }
}
Ulf Åkerstedt
  • 3,086
  • 4
  • 26
  • 28
  • Besides @Nicole's pointers there are some things to consider listed in this answer: http://stackoverflow.com/questions/129453/net-eventhandlers-generic-or-no/129613#129613 – Ulf Åkerstedt Oct 03 '13 at 14:30

1 Answers1

5

There's little reason not to use a generic EventArgs subclass for non-public events. However, for events that are part of a truly public API, things get a bit trickier due to potential backward compatibility concerns. For a publicly consumed event, creating an event-specific EventArgs subclass would give you flexibility to add members without affect the API consumers.

For an event that is not part of a public API, there would still be a bit of potential rework to be done if the EventArgs subclass was changed for a particular event because the generic subclass was no longer a good fit. However, this should usually be fairly minimal, and the compiler should catch any problems (whether explicit or anonymous handler methods are used). Obviously, there's a trade-off to be made there between the initial development effort and the potential change effort -- fwiw, I use a generic EventArgs for internal events where it's a good fit, and I've rarely needed to change one after initial release.

Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49