为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
三国纷争 2019-10-17 15:47:58
在检查事件处理程序是否为null时,这是否基于每个线程进行?确保有人正在听事件是这样完成的:EventSeven += new DivBySevenHandler(dbsl.ShowOnScreen);如果我按照此模式在上面检查空值的位置添加代码,那么为什么我需要进行空值检查(从此站点获取的代码)。我想念什么?此外,事件和GC的规则是什么?
查看完整描述

3 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

问题是,如果没有人订阅该事件,则该事件为null。而且您不能针对null调用。三种方法让人想到:


检查是否为空(请参见下文)

添加“不执行任何操作”处理程序: public event EventHandler MyEvent = delegate {};

使用扩展方法(见下文)

为了确保线程安全,在检查null时,理论上必须首先捕获委托引用(以防在检查和调用之间更改):


protected virtual void OnMyEvent() {

    EventHandler handler = MyEvent;

    if(handler != null) handler(this, EventArgs.Empty);

}

扩展方法具有不寻常的属性,可以在空实例上调用。


    public static void SafeInvoke(this EventHandler handler, object sender)

    {

        if (handler != null) handler(sender, EventArgs.Empty);

    }

    public static void SafeInvoke<T>(this EventHandler<T> handler,

        object sender, T args) where T : EventArgs

    {

        if (handler != null) handler(sender, args);

    }

那么您可以致电:


MyEvent.SafeInvoke(this);

它既是null安全的(通过检查)又是线程安全的(仅通过读取引用一次)。


查看完整回答
反对 回复 2019-10-17
?
潇湘沐

TA贡献1816条经验 获得超6个赞

我想附加一些有关C#6.0语法的简短信息:


现在可以替换为:


var handler = EventSeven;


if (handler != null)

    handler.Invoke(this, EventArgs.Empty);

有了这个:


handler?.Invoke(this, EventArgs.Empty);

将其与表达式成员结合在一起,可以缩短以下代码:

protected virtual void OnMyEvent()

{

    EventHandler handler = MyEvent;

    handler?.Invoke(this, EventArgs.Empty);

}

下降到一个班轮:


protected virtual void OnMyEvent() => MyEvent?.Invoke(this, EventArgs.Empty);

有关空条件运算符的更多信息,请参见MSDN。有关表达式主体的成员,


查看完整回答
反对 回复 2019-10-17
  • 3 回答
  • 0 关注
  • 471 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信