.NET: Как работает исправление состояния гонки EventHandler?

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

class MyClass
{
    public event EventHandler MyEvent;

    public void F()
    {
        EventHandler handler = MyEvent;
        if(handler != null)
            handler(this, EventArgs.Empty);
    }
}

в отличие от неправильного способа сделать это. склонны к этому состоянию гонки:

class MyClass
{
    public event EventHandler MyEvent;

    public void F()
    {
        if(MyEvent != null)
            MyEvent(this, EventArgs.Empty);
    }
}

У меня вопрос, учитывая, что System.Delegate является ссылочным типом: в случае, если MyEvent не равно null, почему

EventHandler handler = MyEvent;

кажется копией его список вызовов вместо получения ссылки.

Я ожидал бы, что если делегат MyEvent назначен переменной 'handler', то, как только кто-то изменит MyEvent, объект, который ' ссылки обработчика также будут изменены.

Очевидно, что это не так, иначе этот изящный маленький шаблон не работал бы.

I 'Я заглянул в исходный код .NET и все еще не нашел там своего ответа (он, вероятно, есть, но я искал его около часа и не нашел, так что вот я). Я также читал, что Спецификация языка C # говорит о событиях и делегатах, но это не касается этого вопроса.

Спасибо за ваше время.

11
задан leppie 3 February 2015 в 12:26
поделиться