Как События C# выполняют незаметную работу?

Предыдущие комментарии об использовании абстрактных классов для общей реализации, безусловно, находятся на грани. Одно из преимуществ, о которых я еще не упоминал, заключается в том, что использование интерфейсов значительно упрощает реализацию макетных объектов для модульного тестирования. Определение IPet и PetBase, как описано Джейсоном Коэном, позволяет легко обманывать различные условия данных без накладных расходов на физическую базу данных (пока вы не решите, что пришло время проверить реальную вещь).

40
задан Matt 2 July 2009 в 14:58
поделиться

2 ответа

Я описал это в изрядном количестве детали в статья , но вот сводка, предполагая, что Вы довольно довольны делегаты сами:

  • событие является просто "добавить" методом и "удалить" методом, таким же образом что свойство является действительно просто "получить" методом и методом "набора". (На самом деле CLI позволяет метод "повышения/огня" также, но C# никогда не генерирует это.) Metadata описывает событие со ссылками на методы.
  • , Когда Вы объявляете подобное полю событие (как Ваш ElementAddedEvent) компилятор генерирует методы и частное поле (того же типа как делегат). В классе, когда Вы обращаетесь к ElementAddedEvent, Вы обращаетесь к полю. Вне класса Вы обращаетесь к полю.
  • , Когда любой подписывается на событие (с + = оператор), который называет добавить метод. Когда они отказываются от подписки (с - = оператор), который называет удалять.
  • Для подобных полю событий, существует некоторая синхронизация, но иначе добавление/удаление просто звонит Делегату. Объединение / Удаляют для изменения значения автоматически сгенерированного поля. Обе из этих операций присваивают отступающему полю - помнят, что делегаты неизменны. Другими словами, автоматически сгенерированный код очень похож на это:

    // Backing field
    // The underscores just make it simpler to see what's going on here.
    // In the rest of your source code for this class, if you refer to
    // ElementAddedEvent, you're really referring to this field.
    private EventHandler<EventArgs> __ElementAddedEvent;
    
    // Actual event
    public EventHandler<EventArgs> ElementAddedEvent
    {
        add
        {
            lock(this)
            {
                // Equivalent to __ElementAddedEvent += value;
                __ElementAddedEvent = Delegate.Combine(__ElementAddedEvent, value);
            }
        }
        remove
        {
            lock(this)
            {
                // Equivalent to __ElementAddedEvent -= value;
                __ElementAddedEvent = Delegate.Remove(__ElementAddedEvent, value);
            }
        }
    }
    
  • начальное значение сгенерированного поля в Вашем случае null - и это будет всегда становиться null снова, если все подписчики будут удалены, поскольку это - поведение Делегата. Удалить.

  • , Если Вы хотите, чтобы обработчик "нет" подписался на Ваше событие, чтобы избежать проверки ничтожности, можно сделать:

    public EventHandler<EventArgs> ElementAddedEvent = delegate {};
    

    Эти delegate {} просто анонимный метод, который не заботится о его параметрах и ничего не делает.

, Если существует что-нибудь, которое это все еще неясно, спросите, и я попытаюсь помочь!

68
ответ дан Jon Skeet 27 November 2019 в 01:42
поделиться

Под капотом события являются просто делегатами со специальными соглашениями о вызовах. (Например, Вы не должны проверять на ничтожность прежде, чем сгенерировать событие.)

В псевдокоде, Событии. Вызовите (), ломается как это:

, Если Событие Сделало, чтобы Слушатели Позвонили каждому слушателю синхронно на этом потоке в произвольном порядке.

события Since многоадресно передаются, у них будут нуль или больше слушателей, сохраненных в наборе. CLR циклично выполнится через них, называя каждого в произвольном порядке.

Один большой протест помнить состоит в том, что обработчики событий выполняются в том же потоке, как событие генерируется в. Это - общая умственная ошибка думать о них как о порождении нового потока. Они не делают.

-3
ответ дан Yes - that Jake. 27 November 2019 в 01:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: