INotifyProperyChanged - 为什么额外的任务?

时间:2012-04-03 06:53:42

标签: c# .net inotifypropertychanged

当以最基本的形式实现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 个答案:

答案 0 :(得分:4)

对临时变量的赋值消除了null检查和最后一个事件订阅者之间竞争条件的可能性,取消订阅。请参阅.NET事件指南here

剪断:

    // 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 :(得分:1)

适用于多线程环境,其他一些线程可能会在执行前将事件设置为null

通过使用局部变量,这将被阻止,并且仍然会调用分配的代理。

答案 2 :(得分:1)

在多线程应用程序中,有可能(在你的第二个例子中)检查是否PropertyChanged != null(让我们假设它不为空)并实际调用委托,你的线程是预先的 - 由另一个取消注册委托中的 last 事件侦听器。然后当原始线程恢复并调用PropertyChanged(this, new PropertyChangedEventArgs(propertyName));时,它现在将为null,并且将抛出NullReferenceException