Heterogeneous Delegate List

Is it possible to create a list containing delegates of different types? For example, these are two delegates:

class MyEventArg1 : EventArgs {} class MyEventArg2 : EventArgs {} EventHandler<MyEventArgs1> handler1; EventHandler<MyEventArgs2> handler2; 

I would like to do something like this:

 List<EventHandler<EventArgs>> handlers = new List<EventHandler<EventArgs>>(); handlers.Add((EventHandler<EventArgs>)handler1); handlers.Add((EventHandler<EventArgs>)handler2); 

But the transfer from one delegate to another seems impossible. My goal is to keep delegates on the list so as not to name them; but just to automatically unregister.

thanks

+4
source share
3 answers

You can do this in C # 4.0 thanks to the dispersion of generics , but before that you need to find another way (maybe ArrayList ).

+1
source

Yes, this does not work, delegates are completely unrelated types. Typically, common types will only have System.Object as the common base type. But here, since they are delegates, you can save them in a List<Delegate> . I doubt that you will help you get them unregistered. But I canโ€™t imagine what this code looks like.

+1
source

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.

0
source

Source: https://habr.com/ru/post/1299202/


All Articles