publisher.MyEvent += subscriber.SomeMethod;
In the above line the the right hand side expression "subscriber.SomeMethod" has the type GenericEventHandler(S sender,A args).
Just as objects are instances of class types , methods are instances of delegate types.
A class specifies the template for an object ... a delegate specifies the signature for a method.... that is parameter and return types. A variable of a delegate type is simply a reference to one of more methods whose signature complies with the one specified in the delegate declaration.
In the older versions of C# you would have to write something like the following :
publisher.MyEvent +=
new GenericEventHandler<MyPublisher,EventArgs>(subscriber.SomeMethod);
In the newer versions of C# , the type of that long ugly looking expression on the right hand side is automatically inferred when you simply provide subscriber.SomeMethod. And it is inferred by the signature of SomeMethod as well as the type of MyEvent ...which is the delegate specifying the signature.
If the code in SomeMethod is really trivial and you will not be calling it from any other place in the program you can totally avoid writing it in a named method (like SomeMethod) and instead use anonymous method syntax as following and write it there and then:
publisher.MyEvent += delegate(MyPublisher s, EventArgs a)
{
/* the SomeMethod Code */
};
Or even better, use Lambda expressions like following:
publisher.MyEvent += (s, a) => {/*the SomeMethod code*/};
In the above lambda expression the types of the parameters 's' and 'a' are automatically inferred from the the type of MyEvent. ... which is ofcourse a delegate specifying the signature.
Now whenever the MyEvent fires the code in the anonymous method or the lambda expression will be executed.