为什么调用一个Action,即null,抛出NullReferenceException?

时间:2013-09-11 12:58:03

标签: c# action nullreferenceexception

为什么我必须检查Action是否不是null以避免获得NullReferenceException?如果没有行动,这是不合逻辑的,那么只是无所事事并继续进行是没有问题的吗?我不明白为什么要抛出异常。 Action是一个类,为什么它自己不处理它?<​​/ p>

3 个答案:

答案 0 :(得分:13)

您正尝试在对象上调用实例方法(Invoke)。如果您使用的是NullReferenceException引用 1 ,那么始终会失败并显示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();
        }
    }
}

use the C# 6 null-conditional operator仅在引用为非null时调用委托:

myAction?.Invoke();

(这适用于任何代理类型,而不仅仅是行动 - 例如,对于EventHandler,您使用类似handler?.Invoke(this, new EventArgs())的内容。EventArgs()构造函数甚至不会被调用handler为空。)


1 至少使用C#。有一些方法可以在IL中非虚拟地“引用”空引用上调用实例方法,但它远非正常。

答案 1 :(得分:8)

从C#6.0开始,您可以:

myAction?.Invoke();

无需扩展方法。

答案 2 :(得分:7)

Action是一个代表,而不是一个类。当你调用一个动作时,如下所示:

myAction();

这里真正发生的是:

myAction.Invoke();

如果myActionnull,则您在Invoke个实例上调用null,这自然会引发NullReferenceException