Подтвердить что ты не робот

Могу ли я изменить порядок событий делегата многоадресной передачи?

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

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

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

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

Ответ 1

Управление, когда и если делегат срабатывает внутри делегата многоадресной передачи

Следующий метод создает делегат многоадресной рассылки, называемый 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])();
    }
}

Ответ 2

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

Например:

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

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

Ответ 3

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