大多数情况下,当我们使用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的回答和解释的例子:
以下是了解此问题的示例代码:
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
当您使用局部变量时,您确保检查无效的引用与用于引发事件的引用相同 - 因此您不会获得异常.还有一个竞争条件,你最终可能会打电话给那些刚刚取消订阅的订阅者,但这是不可避免的.