当以最基本的形式实现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));
}
}
答案 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
。