来自扩展方法的ArgumentNullException还是NullReference

在空实例上调用扩展方法时(扩展方法不允许它),您认为什么是抛出的最佳异常类型?由于扩展方法只不过是静态方法,因此您可以辩称它应该为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);

}

编辑: 在一些答案中,您指出可以像静态方法一样调用扩展方法,在这种情况下,空引用异常将是错误的,这很重要,实际上是我关心的问题之一,不确定为什么我首先忘记了这个问题。


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


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


子衿沉夜
浏览 530回答 4
4回答

宝慕林4294392

通常,包括例外在内,您应该将扩展方法视为普通的静态方法。在这种情况下,您应该抛出ArgumentNullException。由于一些原因,在此处抛出NullReferenceException是一个坏主意实际上没有发生空引用,因此看到一个是违反直觉的抛出NullReferenceException并导致NullReferenceException发生会产生明显不同的异常(一种观察差异的方法是错误代码)。对于CLR抛出的许多异常,这都是正确的。请参阅何时可以捕获StackOverflowException(我在该主题上发表的文章)。像对待常规方法一样调用扩展方法是完全合法的。在那种情况下,除了NullReferenceException外,我当然不会,而是ArgumentNullException。

青春有我

除了所有其他答案(很好)之外,我认为值得一看的是Microsoft为保持一致性所做的事情……据我所知,Enumerable中的扩展方法都抛出ArgumentNullException。

大话西游666

由于扩展方法可以在C#2.0中使用,并且可以像静态方法一样调用它们(您不必将它们用作扩展方法),因此应使用ArgumentNullException。仅仅因为它们看起来像类型上的方法并不意味着它们就是它们,或者总是被称为一个。

catspeake

ArgumentNullException。有没有需要调用扩展方法,好像它们是实例方法。您可以像调用普通方法一样调用它们。在这种情况下,NullReferenceException将完全不正确。
打开App,查看更多内容
随时随地看视频慕课网APP