为什么我们应该使用temprary对象来引发事件?

JSJ*_*JSJ 7 .net c# wpf

大多数情况下,当我们使用MVVM时,我们使用INotifyPropertyChanged接口向绑定提供通知,一般实现如下所示:

public class MyClass : INotifyPropertyChanged
{
    // properties implementation with RaisePropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

每当我从专家那里读到代码时,这对我来说都很好 - 他们写了类似的代码:

public class MyClass : INotifyPropertyChanged
{
    // properties implementation with RaisePropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string propertyName)
    {
        var tempchanged = PropertyChanged;
        if (tempchanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道为PropertyChanged事件创建临时对象的确切原因是什么.

这只是一种好的做法,还是有任何与之相关的其他好处?

我找到了Jon的回答和解释的例子:

了解C#:使用临时变量引发事件

以下是了解此问题的示例代码:

using System;
using System.Collections.Generic;
using System.Threading;

class Plane
{
     public event EventHandler Land;

     protected void OnLand()
     {
          if (null != Land)
          {
               Land(this, null);
           }
      }

     public void LandThePlane()
     {
          OnLand();
      }
}

class Program
{
     static void Main(string[] args)
     {
          Plane p = new Plane();
          ParameterizedThreadStart start = new ParameterizedThreadStart(Run);
          Thread thread = new Thread(start);
          thread.Start(p);

          while (true)
          {
               p.LandThePlane();
           }
      }

     static void Run(object o)
     {
          Plane p = o as Plane;
          while (p != null)
          {
               p.Land += p_Land;
               p.Land -= p_Land;
           }
      }

     static void p_Land(object sender, EventArgs e)
     {
          return;
      }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 25

你不是在创建一个临时对象.您正在使用局部变量来避免竞争条件.

在这段代码中:

if (PropertyChanged != null)
{
    PropertyChanged(...);
}
Run Code Online (Sandbox Code Playgroud)

在无效检查之后,有可能PropertyChanged成为null(由于最后一个用户取消订阅),这意味着你得到一个.NullReferenceException

当您使用局部变量时,您确保检查无效的引用与用于引发事件的引用相同 - 因此您不会获得异常.还有一个竞争条件,你最终可能会打电话给那些刚刚取消订阅的订阅者,但这是不可避免的.