I've built an event system that maintains a dictionary
of delegates, adds/removes elements to this dictionary
via generic Subscribe/Unsubscribe methods (which each take an Action of type
T), and has a Publish method to notify the subscribers when something happens (which also takes an Action of type T). Everything works fine, but I've noticed I cannot use += or -= when adding or removing elements to my dictionary
, as the types passed into the methods (Action of T), do not match the types stored in the dictionary
(Delegate
). The following snippet shows what I can and cannot do.
private readonly Dictionary<Type, Delegate> delegates = new Dictionary<Type, Delegate>();
public void Subscribe<T>(Action<T> del)
{
if (delegates.ContainsKey(typeof(T)))
{
// This doesn't work!
delegates[typeof(T)] += del as Delegate;
// This doesn't work!
delegates[typeof(T)] += del;
// This is ok
delegates[typeof(T)] = (Action<T>)delegates[typeof(T)] + del;
// This is ok
var newDel = (Action<T>)delegates[typeof(T)] + del;
delegates[typeof(T)] = newDel;
// This is ok
del += (Action<T>)delegates[typeof(T)];
delegates[typeof(T)] = del;
// This is ok
delegates[typeof(T)] = Delegate.Combine(delegates[typeof(T)], del);
}
else
{
delegates[typeof(T)] = del;
}
}
I mostly understand Jon Skeet's answer here += operator for Delegate specifically, this part
The binary + operator performs delegate combination when both operands are of some delegate type D. (If the operands have different delegate types, a binding-time error occurs.)
What I don't understand, is this
The compiler turns it into a call to Delegate.Combine
. The reverse operation, using - or -=, uses Delegate.Remove
.
What exactly is going on when I use += or -=, versus Delegate.Combine
? What are the differences between the two, making one implementation valid, and another invalid?
Delegate.Combine
. It doesn't have enough information based on the declared type ofdelegates
to make this decision. – Athalie