从扩展方法的ArgumentNullException或NullReferenceException?

如果在空实例上调用扩展方法(扩展方法不允许),那么你认为什么是最好的exceptiontypes? 由于扩展方法不过是静态方法,所以可以说它应该是ArgumentNullException,但是另一方面它们被用作实例方法,因此使用NullReferenceException可能更自然。 我们来看下面的例子:

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

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

另一个例子是:

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

编辑:在一些答案,你已经指出,扩展方法可以被称为像一个静态方法,在这种情况下,空引用exception将是错误的,这是一个伟大的观点,实际上我的一个担心,不知道为什么我忘了在第一个问题中提到这个问题。

有人还指出,抛出一个NullReferenceException是错误的,是的。 这就是为什么我不扔它,我只是让它发生(让CLR扔它)不守护的方法。

我认为我赞成ArgumentNullException(这是我迄今为止使用的),但是我仍然认为至less有空间来反对NullReferenceException,因为在将要使用该方法的大多数地方它似乎更自然。

一般来说,包含exception,你应该把扩展方法看作是一个正常的静态方法。 在这种情况下,你应该抛出一个ArgumentNullException。

抛出一个NullReferenceException在这里是一个坏主意有几个原因

  • 空引用实际上并没有发生,所以看到一个是违反直觉的
  • 抛出一个NullReferenceExceptionexception并导致一个NullReferenceExceptionexception发生,产生明显不同的exception(一种方法是查看差异是错误码)。 CLR引发的很多例外情况都是如此。

看看你什么时候可以捕获一个StackOverflowException (这个主题上的一篇文章)。

  • 像扩展方法一样,调用扩展方法是完全合法的。 在这种情况下,我肯定不会除了一个NullReferenceException,而是一个ArgumentNullException。

除了所有其他答案(这是好的),我认为值得一提的是,为了保持一致性,微软的工作是值得的… Enumerable中的扩展方法都抛出了ArgumentNullException,据我所知。

由于扩展方法可以在C#2.0中使用,并且可以像静态方法一样调用(您不必将它们用作扩展方法),所以应该使用ArgumentNullException。

只是因为他们看起来像这种types的方法并不意味着他们是或总是被称为一个。

从用户的angular度来看,该方法看起来像一个实例方法,所以如果我是他们,我期望看到一个NullReferenceException。

也就是说,我build议在代码中明确地抛出一个或另一个,而不是像第一个例子那样只是“发生”抛出一个。

ArgumentNullException。 不需要像扩展实例方法那样调用扩展方法。 你可以打电话给他们,就好像他们是正常的方法。 在这种情况下,NullReferenceException将是完全不正确的。