Если я зарегистрируюсь на событие в c # во время его отправки, я гарантирую, что мне больше не позвонят во время этой отправки? - PullRequest
4 голосов
/ 26 сентября 2008

В C # я иногда хочу зарегистрировать метод для события в середине отправки того же самого события. Например, если у меня есть класс, который передает состояния на основе последовательных отправлений одного и того же события, я мог бы захотеть, чтобы обработчик первого состояния отменил свою регистрацию и зарегистрировал второй обработчик. Однако я не хочу, чтобы второй обработчик отправлялся до следующего запуска события.

Хорошей новостью является то, что, похоже, реализация Microsoft C # ведет себя именно так. Синтаксический синтаксис регистрации события заменяется вызовом System.Delegate.Combine, который просто объединяет текущий список вызовов и новый метод в отдельный список и назначает его свойству события. Это дает мне именно то поведение, которое я хочу.

Итак, мой вопрос: это гарантированное поведение в соответствии со стандартом языка? Мне нравится иметь возможность запускать мой код C # на других платформах под управлением mono и, как правило, хочу убедиться, что я не делаю предположений относительно языкового стандарта на основе его реализации.

Я не смог найти точную информацию о MSDN.

Если вы хотите конкретный пример того, о чем я говорю, вот пример:

    delegate void TestDelegate();
    static event TestDelegate TestEvent;

    static void Main (string[] args) {
        TestEvent += TestDelegateInstanceFirst;
        TestEvent();
        TestEvent();
    }

    static void TestDelegateInstanceFirst () {
        Console.WriteLine("First");
        TestEvent += TestDelegateInstanceSecond;
    }

    static void TestDelegateInstanceSecond () {
        Console.WriteLine("Second");
    }

По крайней мере в Windows вывод:

First
First
Second

1 Ответ

8 голосов
/ 26 сентября 2008

Да, это гарантировано.

Из унифицированной спецификации C # 3.0, раздел 15.1:

Однако, когда два ненулевых делегата экземпляры объединены, их списки вызовов объединяются - в порядок слева операнд, затем право операнд - для формирования нового списка вызовов, который содержит две или более записей.

Обратите внимание на «новый список вызовов». И снова в разделе 15.3:

После создания экземпляра делегировать экземпляры всегда ссылаются на один и тот же целевой объект и метод. Помните, когда два делегаты объединены, или один удален от другого, новый делегат результаты с собственным списком вызовов; списки вызовов делегатов в сочетании или удалены остаются без изменений.

Наконец, MSDN для System.Delegate сообщает:

Делегаты неизменны; однажды созданный, список вызовов делегата делает не меняется.

Я подозреваю, что в спецификации CLI есть что-то - я проверю, хотите ли вы, но, надеюсь, эти три дали вам достаточно уверенности:)

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