It is possible that the declaration of the general delegate indicates that certain type parameters should be covariant or contravariant, which will allow the use of assignment types. Unfortunately, the internal implementation of multicast delegates makes it impossible to combine delegates of different types (a "simple" delegate contains information about its type, a method pointer and a link to its target; the delegate multicast information about its type along with pointers to methods and target links for each from its composite delegates, but does not contain references to the original delegates that were merged, and does not contain any information about their types). Trying to combine EventHandler<DerivedEventArgs> with EventHandler<EventArgs> in this way will not work at runtime.
If the EventHandler<T> were contravariant with respect to T , try to pass the EventHandler<EventArgs> method with the standard AddHandler event, which expects the EventHandler<DerivedEventArgs> to compile and even succeed if no other handlers are signed, because EventHandler<EventArgs> will Delegate.Combine d with null , so it will be saved in the event delegation field as EventHandler<EventArgs> . Unfortunately, a subsequent attempt to add an EventHandler<DerivedEventArgs> (which is actually the expected type) will fail because its type does not match the delegate with which it is associated. Microsoft decided that this behavior would violate the Least of Surprise Principle (if transferring the โwrongโ delegate would cause any problem, it should do it when that delegate is transferred, and not when a later one is transferred) and decided to minimize the likelihood of a scenario by making it so that an attempt is made to pass the EventHandler<EventArgs> handler that expects the EventHandler<DerivedEventArgs> to complete compilation, even if the action could be successful if it was the only subscription.
source share