为什么调用一个 Action(即 null)会抛出 NullReferenceException
本文关键字:null NullReferenceException 一个 调用 为什么 Action | 更新日期: 2023-09-27 18:30:52
为什么我必须检查Action
是否未null
以避免NullReferenceException
?如果没有行动,那么什么都不做就可以继续,这不是合乎逻辑的吗?我不明白为什么它必须抛出异常。 Action
是一个类,为什么它不自己处理呢?
您正在尝试在对象上调用实例方法 ( Invoke
)。如果您使用的是null
引用1,则执行此操作始终会失败并显示NullReferenceException
。例如:
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 null 条件运算符仅在引用为非 null 时调用委托:
myAction?.Invoke();
(这适用于任何委托类型,而不仅仅是操作 - 例如EventHandler
,您将使用 handler?.Invoke(this, new EventArgs())
.如果 EventArgs()
为 null,则甚至不会调用 handler
构造函数。
1 至少使用 C#。有一些方法可以在 IL 中非虚拟地"在"空引用上调用实例方法,但这远非正常情况。
从 C# 6.0 开始,您可以:
myAction?.Invoke();
无需扩展方法。
Action
是一个委托,而不是一个类。当您调用操作时,如下所示:
myAction();
这里真正发生的事情是这样的:
myAction.Invoke();
如果myAction
null
则在null
实例上调用Invoke
,这自然会引发NullReferenceException
。