tags:

views:

125

answers:

3

When you subscribe to an event in .NET, the subscription is added to a multicast delegate. When the event is fired, the delegates are called in the order they were subscribed.

I'd like to override the subscription somehow, so that the subscriptions are actually fired in the reverse order. Can this be done, and how?

I think something like this might be what I need?:

public event MyReversedEvent
{
    add { /* magic! */ }
    remove { /* magic! */ }
}
+5  A: 

One option would be to handle this when you raise the event. You can get the event subscribers via Delegate.GetInvocationList, and just call each delegate in reverse order yourself.

Reed Copsey
**Wrong**. You can do this.
SLaks
Thanks - I tried this myself just before you posted your answer and got it working - good to see confirmation that I've done the right thing. :)
Neil Barnwell
@SLaks: Interesting. Thanks - hadn't used the delegate operators in that way before...
Reed Copsey
+4  A: 

Controlling When and If a Delegate Fires Within a Multicast Delegate

The following method creates a multicast delegate called allInstances and then uses GetInvocationList to allow each delegate to be fired individually, in reverse order:

public static void InvokeInReverse()
{
    MyDelegate myDelegateInstance1 = new MyDelegate(TestInvoke.Method1);
    MyDelegate myDelegateInstance2 = new MyDelegate(TestInvoke.Method2);
    MyDelegate myDelegateInstance3 = new MyDelegate(TestInvoke.Method3);

    MyDelegate allInstances =
            myDelegateInstance1 +
            myDelegateInstance2 +
            myDelegateInstance3;

    Console.WriteLine("Fire delegates in reverse");
    Delegate[] delegateList = allInstances.GetInvocationList();
    for (int counter = delegateList.Length - 1; counter >= 0; counter--)
    {
        ((MyDelegate)delegateList[counter])();
    }
}
Robert Harvey
Thanks - I tried this myself just before you posted your answer and got it working - good to see confirmation that I've done the right thing. :)
Neil Barnwell
+10  A: 

You don't need any magic; you just need to reverse the addition.
Writing delegate1 + delegate2 returns a new delegate containing the method(s) in delegate1 followed by the methods in delegate2.

For example:

private EventHandler myReversedEventField;
public event EventHandler MyReversedEvent
{
    add { myReversedEventField = value + myReversedEventField; }
    remove { myReversedEventField -= value; }
}

You don't need any magic in the remove handler, unless you want to remove the last occurrence of that handler instead of the first. (In case the same handler was added twice)

SLaks
Can you expand on your answer a little, please? It would be good to see the context around the code you posted, so I can see where I should put it.
Neil Barnwell
@SLaks thanks for the update to your answer.
Neil Barnwell
@Neil, Some background information here: http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/
Robert Harvey