在事件处理程序中使用空值检查

在检查事件处理程序是否为null时,这是否基于每个线程进行?


确保有人正在听事件是这样完成的:


EventSeven += new DivBySevenHandler(dbsl.ShowOnScreen);

如果我按照此模式在上面检查空值的位置添加代码,那么为什么我需要进行空值检查(从此站点获取的代码)。我想念什么?


此外,事件和GC的规则是什么?


三国纷争
浏览 474回答 3
3回答

慕码人8056858

问题是,如果没有人订阅该事件,则该事件为null。而且您不能针对null调用。三种方法让人想到:检查是否为空(请参见下文)添加“不执行任何操作”处理程序: public event EventHandler MyEvent = delegate {};使用扩展方法(见下文)为了确保线程安全,在检查null时,理论上必须首先捕获委托引用(以防在检查和调用之间更改):protected virtual void OnMyEvent() {&nbsp; &nbsp; EventHandler handler = MyEvent;&nbsp; &nbsp; if(handler != null) handler(this, EventArgs.Empty);}扩展方法具有不寻常的属性,可以在空实例上调用。&nbsp; &nbsp; public static void SafeInvoke(this EventHandler handler, object sender)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (handler != null) handler(sender, EventArgs.Empty);&nbsp; &nbsp; }&nbsp; &nbsp; public static void SafeInvoke<T>(this EventHandler<T> handler,&nbsp; &nbsp; &nbsp; &nbsp; object sender, T args) where T : EventArgs&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (handler != null) handler(sender, args);&nbsp; &nbsp; }那么您可以致电:MyEvent.SafeInvoke(this);它既是null安全的(通过检查)又是线程安全的(仅通过读取引用一次)。

潇湘沐

我想附加一些有关C#6.0语法的简短信息:现在可以替换为:var handler = EventSeven;if (handler != null)&nbsp; &nbsp; handler.Invoke(this, EventArgs.Empty);有了这个:handler?.Invoke(this, EventArgs.Empty);将其与表达式成员结合在一起,可以缩短以下代码:protected virtual void OnMyEvent(){&nbsp; &nbsp; EventHandler handler = MyEvent;&nbsp; &nbsp; handler?.Invoke(this, EventArgs.Empty);}下降到一个班轮:protected virtual void OnMyEvent() => MyEvent?.Invoke(this, EventArgs.Empty);有关空条件运算符的更多信息,请参见MSDN。有关表达式主体的成员,
打开App,查看更多内容
随时随地看视频慕课网APP