INotifyProperyChanged - зачем дополнительное назначение? - PullRequest
5 голосов
/ 03 апреля 2012

При реализации интерфейса INotifyPropertyChanged в его наиболее простой форме большинство людей, похоже, реализуют его следующим образом:

public virtual void OnPropertyChanged(string propertyName)
{
    var propertyChanged = PropertyChanged;
    if (propertyChanged != null)
    {
        propertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

У меня вопрос: зачем дополнительное назначение var propertyChanged = PropertyChanged;? Это просто вопрос предпочтений, или для этого есть веская причина? Наверняка следующее так же верно?

public virtual void OnPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Ответы [ 3 ]

4 голосов
/ 03 апреля 2012

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

Snip:

    // Make a temporary copy of the event to avoid possibility of
    // a race condition if the last subscriber unsubscribes
    // immediately after the null check and before the event is raised.
    EventHandler<CustomEventArgs> handler = RaiseCustomEvent; 
1 голос
/ 03 апреля 2012

В многопоточном приложении возможно, что (во втором примере) между проверкой, чтобы увидеть, если PropertyChanged != null (допустим, он не равен нулю), и фактическим вызовом делегата, ваш поток будет прерван другим, которыйотмена регистрации прослушивателя событий last от делегата.Затем, когда исходный поток возобновляет работу и вызывает PropertyChanged(this, new PropertyChangedEventArgs(propertyName));, он теперь будет нулевым, а NullReferenceException будет выброшено.

1 голос
/ 03 апреля 2012

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

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

...