为什么我必须检查 an Action
is 不是null
为了避免得到 a NullReferenceException
?如果不采取任何行动,这不是合乎逻辑的,那么什么都不做并继续进行是可以的吗?我不明白为什么它必须抛出异常。Action
是一个类,为什么它自己不处理这个?
3 回答
您正在尝试Invoke
在对象上调用实例方法 ( )。如果您使用参考1,这样做总是会失败。例如:NullReferenceException
null
object x = null;
string y = x.ToString();
也应该object.ToString()
处理?
基本上,这与类型系统其余部分的工作方式是一致的。C# 语言本可以以不同的方式设计——可能只是为了action()
意义的“速记” action.Invoke()
——但事实并非如此,而且现在也不会改变。
Action
如果您愿意,可以很容易地添加自己的扩展方法:
public static class ActionExtensions
{
public static void NullSafeInvoke(this Action action)
{
if (action != null)
{
action();
}
}
}
或者使用 C# 6空条件运算符仅在引用为非空时调用委托:
myAction?.Invoke();
(这适用于任何委托类型,而不仅仅是操作 -EventHandler
例如,您可以使用类似handler?.Invoke(this, new EventArgs())
的东西。如果为 null,EventArgs()
则甚至不会调用构造函数。)handler
1至少使用 C#。在 IL 中,有一些方法可以非虚拟地“在”空引用上调用实例方法,但这与正常情况相去甚远。
从 C# 6.0 开始,您可以:
myAction?.Invoke();
不需要扩展方法。
Action
是一个代表,而不是一个类。当你调用一个动作时,像这样:
myAction();
这里真正发生的是:
myAction.Invoke();
如果你myAction
正在null
调用Invoke
一个null
实例,这自然会引发一个NullReferenceException
.