Adding one event handler to another

.net, c#, delegates, event-handling

Solution

The problem is that `Delegate`s are immutable.

If you add a handler to an event, it creates a new `Delegate` instance which contains the old handlers and the newly added handler. The old `Delegate` is not modified and is discarded.

When I write, `value.AnEvent += AnEvent`, it adds the `Delegate` containing 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 the `Delegate` instance that I added to the inner classes event. Similarly, if I remove a handler after setting the `Inner` property, 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:

public event EventHandler AnEvent;

public OtherClass Inner {
    get { /* ... */ }
    set {
        if(Inner != null)
            Inner.AnEvent -= Inner_AnEvent;

        //...

        if(value != null)
            value.AnEvent += Inner_AnEvent;

        //...
    }
}

void Inner_AnEvent(object sender, EventArgs e) { 
    var handler = AnEvent;
    if (handler != null) handler(sender, e);
}

The other way is to make a custom event in the wrapper that adds its handlers to the inner class's event, like this:

EventHandler anEventDelegates

public OtherClass Inner {
    get { /* ... */ }
    set {
        //...
        if(value != null)
            value.AnEvent += anEventDelegates;
        //...
    }
}
public event EventHandler AnEvent {
    add {
        anEventDelegates += value;
        if (Inner != null) Inner.AnEvent += value;
    }
    remove {
        anEventDelegates -= value;
        if(Inner != null) Inner -= value;
    }
}

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.

Problem

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?

Original source