I don't think generic event handlers can exist. What you mean is probably the generic type
System.EventHandler
:
http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx[
^].
The confusing part is: this is the generic delegate type called
EventHandler
, which is
not an event handler itself, but a delegate type which, in particular, defines the signature of an event handler. And the event handler is always a
method
(named or
anonymous) which is used to be added to the invocation type of an event instance. In addition to this confusion, the event instance type is not a type used in its declaration. It's the instance of some class. In other words, the declarations
int Value;
internal event EventHandler<MyEventArgs> SomethingHappened;
their meaning is dramatically different: in first case, the type of the object is the same as declared type on the left of it; in the second case, the actual type of the event instance (object) and the declared type are unrelated.
Now, let's start from the very beginning and show the complete sample. Here is the declaration of event:
public class MyEventArgs : System.EventArgs {
internal MyEventArgs();
public
}
public class MyEventDeclaringClass {
public event EventHandler<MyEventArgs> SomethingHappened;
internal InvokeWhenSomethingHappened() {
if (SomethingHappened != null)
SomethingHappened.Invoke(this, new MyEventArgs());
}
}
By using some
public
declarations above, I assumed that the class
MyEventDeclaringClass
and handling its event can be possible in the same assembly or on some other assembly. And now, the usage:
MyEventDeclaringClass myInstance = new MyEventDeclaringClass();
myInstance.SomethingHappened += (sender, eventArgs) => {
};
myInstance.SomethingHappened += delegate(System.Object sender, MyEventArgs eventArgs) { }
As you can see, the generic type
System.EventHandler<>
allows to abstract out the actual type of the event arguments and at the same time avoid type cast which would be needed for non-generic
System.EventHandler
. In other words, it is used for the same purposes generics are used for in other cases.
This is not required formally, but recommended way of using the mechanism of events. You need to use always two parameters, first should be
object
, and the second one should be the custom type always derived from
System.EventArgs
.
See also:
http://en.wikipedia.org/wiki/Anonymous_method[
^],
http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx[
^];
http://en.wikipedia.org/wiki/Type_inference[
^],
http://msdn.microsoft.com/en-us/library/bb308966.aspx#csharp3.0overview_topic10[
^],
http://msdn.microsoft.com/en-us/vstudio/jj131514.aspx[
^].
[EDIT #1]
By the way, confusing naming is pretty usual. For example, the name
System.Object
is the name of the
class, not object. For those who understand the essence of things, this is not really a problem. Also, the syntax allows to give a variable or a type's member the same name as its type; and this is even recommended. You need first to distinguish between types, instances (objects), variable, type's fields, properties (and other members), and then consider their roles.
[EDIT #2]
Please see also my past answers to related questions:
how to call keydown event on particular button click[
^],
[Solved] How to add Event for C# Control[
^],
A question about usercontrols, nested controls and encapsulation.[
^],
WPF : How to Use Event in Custom Control[
^].
And, more on anonymous methods and such non-trivial thing as
closure:
What are Anonymous Types in C#?[
^],
Looping for creating new thread give some problem[
^],
http://en.wikipedia.org/wiki/Closure_%28computer_science%29[
^].
—SA