Могу ли я изменить порядок события делегата многоадресной рассылки? - PullRequest
12 голосов
/ 10 июня 2010

Когда вы подписываетесь на событие в .NET, подписка добавляется в делегат многоадресной рассылки. Когда событие инициируется, делегаты вызываются в том порядке, в котором они были подписаны.

Я бы хотел как-то переопределить подписку, чтобы подписки фактически запускались в порядке обратный . Можно ли это сделать и как?

Я думаю, что-то вроде этого может быть тем, что мне нужно?:

public event MyReversedEvent
{
    add { /* magic! */ }
    remove { /* magic! */ }
}

Ответы [ 3 ]

19 голосов
/ 10 июня 2010

Вам не нужна магия; вам просто нужно отменить сложение.
Запись delegate1 + delegate2 возвращает новый делегат, содержащий методы в delegate1, за которыми следуют методы в delegate2.

Например:

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

Вам не нужно никакого волшебства в обработчике remove, если только вы не хотите удалить последнее вхождение этого обработчика вместо первого. (Если один и тот же обработчик был добавлен дважды)

5 голосов
/ 10 июня 2010

Управление тем, когда и если делегат запускается в многоадресном делегате

Следующий метод создает делегат многоадресной передачи с именем allInstances, а затем использует GetInvocationList для разрешениякаждый делегат увольняется индивидуально, в обратном порядке:

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])();
    }
}
5 голосов
/ 10 июня 2010

Один из вариантов будет обрабатывать это, когда вы поднимаете событие. Вы можете получить подписчиков события через Delegate.GetInvocationList , и просто позвонить каждому делегату в обратном порядке самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...