MSDN is perfectly helpful in case of .NET, for those who can add and understand documentation.
Your considerations about the case when you "have the same result" is the bright case of false proof. Who told you that you should always derive from
System.EventArgs
class? For many events, it is really not needed. Those are the events when no information need to be passed from the code where the event is invoked (which is possible only in the class declaring the event), to the event handler.
The example of the events when no information is passed throw
EventArgs
(as you can see, I don't count the first parameter of the event handler,
Object sender
which is always passed and rarely used), is the event like
Button.Click
. For the event handler, nothing is important except the fact that some button is just clicked. For the logic on the button functionality, it is not important, how it was "clicked", by a real click of a mouse of by blank space key, or, maybe, by selecting the button and then hitting Enter; if a mouse was used, the position of mouse pointer inside the button's client are is not important. Such approach is very good, because it helps to unify all kinds of "click" to handle then in the same way.
To find an example of the cases when deriving of the
EventArgs
class is really important, it's enough to take a look at on of the many available events. Let's, for example, look at the event
System.Windows.Control.MouseDown
:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousedown.aspx[
^].
As you can see, the signature of the handler is defined by the type
MouseHandler
, which can be defined as
System.EventArgs<System.Windows.Forms.MouseEventArgs>
:
http://msdn.microsoft.com/en-us/library/system.windows.forms.mouseeventargs.aspx[
^].
As you can see, this type inherited from
System.EventArgs
provides additional properties to pass information on the mouse button which was clicked, mouse pointer location, and so on. In turn, this type is used as a base type to other event arguments types used for more specialized events, such as the ones for a tree node, etc.; naturally, some control-specific information is also passed.
According to the event declaration, the signature of the event handler includes the second parameter of the type
System.Windows.Forms.MouseEventArgs
:
myControl.MouseDown += delegate(object sender, System.Windows.Forms.MouseEventArgs eventArgs) {
};
I intentionally did not use lambda form of the event handler in the above code sample, to demonstrate the signature of the handler explicitly. With lambda, type inference can be used (with C# v.3 and above):
myControl.MouseDown += (sender, eventArgs) => {
};
When you need to create a custom event in your own class, you can use one of the available event argument classes. However, if you need to handle your event with passing some parameters specific to your class, you would need to declare your own event argument class and add some new properties to it. The base class can be
System.EventArgs
, but not always, sometime you can use some more derived event argument classes for your base class.
[EDIT]
It's important to understand that the use of the delegate type
System.EventArgs
or the generic delegate type
System.EventArgs<>
is just a recommended practice and not formally required by CLR and syntax. However, this is the highly recommended pattern for events (but not for other delegate instances, which can use any delegate types).
Please see my comments below to the answer.
—SA