5

为什么我必须检查 an Actionis 不是null为了避免得到 a NullReferenceException?如果不采取任何行动,这不是合乎逻辑的,那么什么都不做并继续进行是可以的吗?我不明白为什么它必须抛出异常。Action是一个类,为什么它自己不处理这个?

4

3 回答 3

17

您正在尝试Invoke在对象上调用实例方法 ( )。如果您使用参考1,这样做总是会失败。例如:NullReferenceExceptionnull

 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 中,有一些方法可以非虚拟地“在”空引用上调用实例方法,但这与正常情况相去甚远。

于 2013-09-11T13:04:19.747 回答
14

从 C# 6.0 开始,您可以:

myAction?.Invoke();

不需要扩展方法。

于 2016-02-09T11:01:17.517 回答
8

Action是一个代表,而不是一个类。当你调用一个动作时,像这样:

myAction();

这里真正发生的是:

myAction.Invoke();

如果你myAction正在null调用Invoke一个null实例,这自然会引发一个NullReferenceException.

于 2013-09-11T13:01:04.493 回答