【发布时间】:2011-06-02 18:23:14
【问题描述】:
我需要在更改属性时触发一个事件。当我运行此代码时,我得到一个未设置为对象实例的对象引用。我究竟做错了什么?实例化事件并在设置属性时触发它的正确方法是什么?
公共成员:
public event System.EventHandler ClassChanged;
属性集:
ClassChanged(this, EventArgs.Empty);
【问题讨论】:
我需要在更改属性时触发一个事件。当我运行此代码时,我得到一个未设置为对象实例的对象引用。我究竟做错了什么?实例化事件并在设置属性时触发它的正确方法是什么?
公共成员:
public event System.EventHandler ClassChanged;
属性集:
ClassChanged(this, EventArgs.Empty);
【问题讨论】:
您需要先验证事件处理程序不为空:
if (ClassChanged != null)
ClassChanged(this, EventArgs.Empty);
但一般来说,您可能希望将其包装成一个辅助方法,如下所示:
private void NotifyClassChanged() {
if (ClassChanged != null)
ClassChanged(this, EventArgs.Empty);
}
或者可能实现INotifyPropertyChanged。
【讨论】:
NullReferenceException。
试试这个:
System.EventHandler handler = this.ClassChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
【讨论】:
这样做是因为没有事件处理程序已订阅该事件。
确保事件的多播委托不是线程安全的null 的正确方法:
var cc = ClassChanged; //makes a copy
if (cc != null)
cc(this, EventArgs.Empty);
但是,我更喜欢的方法是使用空的 lambda 处理程序声明事件,因此它永远不会是 null:
public event EventHandler ClassChanged = (o,e) => {};
【讨论】:
public,什么是阻止某人设置:ClassChanged = null?为了安全起见,最好为竞争条件添加 null 检查。
+= 添加处理程序并使用-= 删除处理程序。 event 声明是带有支持委托的 AddHandler 和 RemoveHandler(而不是 get 和 set)属性的语法糖。
就像 joel 说的那样,这个方法没有附加列表,这就是你得到异常的原因。另一种处理方法是创建一个方法,该方法检查其是否为 null,然后调用此方法而不是 Event
如果你有
public event System.EventHandler ClassChanged;
ClassChanged(this, EventArgs.Empty);
您创建以下方法
private void OnClassChanged()
{
if (ClassChanged != null)
{
ClassChanged(this, EventArgs.Empty);
}
}
并调用 OnClassChanged(...) 而不是 ClassChanged(...) 事件
【讨论】:
可能是没有附加到 ClassChanged 的事件处理程序。 (看不到其余代码) 因此,在触发之前先检查 ClassChanged 是否不为空。
if (ClassChanged != null)
{
ClassChanged(this, nully);
}
【讨论】: