I have a class which wraps another class and exposes several events from the class it’s wrapping. (The instance it wraps can change)
I used the following code:
public event EventHandler AnEvent;
public OtherClass Inner {
get { /* ... */ }
set {
//...
if(value != null)
value.AnEvent += AnEvent;
//...
}
}
However, the events were raised inconsistently.
What’s wrong with this code?
The problem is that
Delegates are immutable.If you add a handler to an event, it creates a new
Delegateinstance which contains the old handlers and the newly added handler. The oldDelegateis not modified and is discarded.When I write,
value.AnEvent += AnEvent, it adds theDelegatecontaining the current handlers (if any) to the inner class’s event. However, changes to the outer class’s event are ignored because they don’t change theDelegateinstance that I added to the inner classes event. Similarly, if I remove a handler after setting theInnerproperty, the handler isn’t removed from the inner class’s event.There are two correct ways to do this.
I can make my own handler that invokes the wrapper’s event, like this:
The other way is to make a custom event in the wrapper that adds its handlers to the inner class’s event, like this:
Note that this is not entirely thread-safe.
I solved this problem myself and am posting the question & answer for the benefit of people with similar problems.