PropertyChangedEventHandler如何工作?

这是一个非常简单的问题,但我想知道是否有人可以解释第4行实际上在做什么? 所以第一行给处理程序一个事件。 我真的不知道在什么情况下处理程序将返回null或最后一行的作用。

当你传递处理程序你的对象和哪个属性发生了变化时,它对它们有什么影响?

PropertyChangedEventHandler handler = PropertyChanged; //property changed is the event if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } 

我假设我使用它来获取此代码,但我想了解它正在做什么。

如果你刚刚做了:

 PropertyChanged(this, new PropertyChangedEventArgs(name)) 

如果没有人订阅PropertyChanged事件,你会得到一个NullReferenceException 。 要抵消这一点,你需要添加一个空检查:

 if(PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)) } 

现在,如果您使用multithreading,则可以取消订阅null检查和事件调用,因此您仍然可以获得NullReferenceException 。 为了处理这个问题,我们将事件处理程序复制到临时变量

  PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } 

现在,如果某人取消订阅该事件,我们的临时变量handler仍将指向旧函数,此代码现在无法抛出NullReferenceException

大多数情况下,您会看到人们使用关键字var代替,这使得您无需输入完整类型的临时变量,这是您在代码中最常见到的表单。

  var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(name)); } 

PropertyChanged是根据接口中的定义声明的事件:

 public event PropertyChangedEventHandler PropertyChanged; 

这样定义的事件实际上是事件处理程序列表的语法糖,您可以通过订阅添加委托(即对函数的引用),或通过取消订阅删除委托。

现在,当您调用一个事件,即PropertyChanged(...) ,内部发生的事情是该内部列表中的每个委托都使用参数单独调用。 这将告诉您事件的所有订阅者事件发生。

现在, handler变量的全部原因是, PropertyChanged可以为null。 如果没有订阅它,那么调用事件(或者更确切地说是事件处理程序列表)将不起作用,因此这只是一种确保您可以实际执行处理程序的方法。

如果没有处理程序订阅该事件 ,则handler可以为null,第四行引发给定属性名称的事件(执行所有已订阅的处理程序)。

通常,当您使用绑定时,WPF框架将订阅PropertyChanged ,因此它可以在绑定属性更改后更新绑定。