扩展方法中的 ArgumentNullException 或 NullReferenceException?

2024-03-19

在空实例上调用扩展方法(扩展方法不允许)时,您认为抛出的最佳异常类型是什么?由于扩展方法只不过是静态方法,您可能会认为它应该是 ArgumentNullException,但另一方面,它们的使用方式与实例方法类似,因此使用 NullReferenceException 可能更自然。让我们看下面的例子:

public static string ToInvariantString(this IFormattable value, string format)
{
    return value.ToString(format, CultureInfo.InvariantCulture);
}

这样,如果 value 参数为 null,则会抛出 NullReferenceException。

另一个例子是:

public static string ToInvariantString(this IFormattable value, string format)
{
    if (value == null) throw new ArgumentNullException("value");
    return value.ToString(format, CultureInfo.InvariantCulture);
}

EDIT:在一些答案中,您指出扩展方法可以像静态方法一样被调用,在这些情况下,空引用异常将是错误的,这是一个很好的观点,实际上也是我关心的问题之一,不知道为什么我忘记了首先在问题中提到这一点。

也有人指出抛出 NullReferenceException 是错误的,是的,确实如此。这就是为什么我不抛出它,我只是通过不保护该方法让它发生(让 CLR 抛出它)。

我认为我赞成 ArgumentNullException (这就是我到目前为止所使用的),但我仍然认为至少有空间反对 NullReferenceException,因为在大多数要使用该方法的地方它似乎更自然。


一般来说,包括例外情况,您应该将扩展方法视为普通的静态方法。在这种情况下,您应该抛出 ArgumentNullException。

出于以下几个原因,在这里抛出 NullReferenceException 是一个坏主意

  • 空引用实际上并未发生,因此看到空引用是违反直觉的
  • 引发 NullReferenceException 和导致 NullReferenceException 发生会产生明显不同的异常(查看差异的一种方法是错误代码)。 CLR 引发的许多异常都是如此。

See 什么时候可以捕获 StackOverflowException https://learn.microsoft.com/en-us/archive/blogs/jaredpar/when-can-you-catch-a-stackoverflowexception(我就这个主题发表过一篇文章)。

  • 调用扩展方法就像调用常规方法一样是完全合法的。在这种情况下,我当然不会排除 NullReferenceException,而是排除 ArgumentNullException。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

扩展方法中的 ArgumentNullException 或 NullReferenceException? 的相关文章

随机推荐