我对我经常在网上偶然发现的一段代码有疑问。例如
public static event Action<Foo> foo = delegate{ };
我得到了声明的左侧。但右手边令人困惑。将事件分配给带空括号的委托有什么意义?
我对我经常在网上偶然发现的一段代码有疑问。例如
public static event Action<Foo> foo = delegate{ };
我得到了声明的左侧。但右手边令人困惑。将事件分配给带空括号的委托有什么意义?
更新:在现代版本的 C# 中,推荐使用的模式是将其保留为 null 并使用?.
运算符:
event Action<Foo> foo; // leave it as null as the default
// ...
foo?.(new Foo());
在旧版本的 C# 中,这种模式的原因可能是event
字段的默认值为null
. 这需要每次您想要引发事件时都使用空检查 - 调用foo()
未初始化的event
字段将导致NullReferenceException
. 只给它一个合理的默认值(如 no-op)会更方便,这样您就可以直接引发事件,而无需使用包装方法或任何东西。
委托成员的默认值为null
,因此,如果您不为其分配任何内容,则NullReferenceException
在您尝试调用它时会抛出 a 。您可以很容易地看出这可能是一个问题:想象一下,如果您必须订阅OnKeyDown
每个控件!
方便地,标准库中的事件是受保护的,它做同样的事情:
Event handler = OnClick
if (handler != null)
handler(this, new EventArgs());
这是我推荐的形式,因为 - 无论如何对我来说 - 它看起来更干净。另外,请注意局部变量的使用。写成这样是合法的
if(OnClick != null) OnClick(this, new EventArgs());
但这不是线程安全的,因为 OnClick 的侦听器可以在 null 检查和调用之间取消订阅。