C#:在扩展方法中validation“this”参数的最佳实践

假设我有一个扩展方法

public static T TakeRandom(this IEnumerable e) { ... 

要validation参数e,我应该:

A)if(e == null)抛出新的NullReferenceException()
B)if(e == null)抛出新的ArgumentNullException(“e”)
C)不检查e

什么是共识?

我的第一个想法是始终validation参数,因此抛出ArgumentNullException。 然后,由于TakeRandom()成为e的方法,也许它应该是NullReferenceException。 但是如果它是NullReferenceException,如果我尝试在TakeRandom()中使用e的成员,那么无论如何都会抛出NullReferenceException。

也许我应该使用Reflector达到峰值并找出框架的作用。

你应该抛出一个ArgumentNullException。 您正在尝试进行参数validation,因此应该抛出一个针对参数validation的exception。 NullReferenceException不是参数validationexception。 这是一个运行时错误。

不要忘记,扩展方法只是引擎盖下的静态方法,可以这样调用。 虽然表面上看起来似乎有理由在扩展方法上抛出NullReferenceException,但对于静态方法这样做是没有意义的。 无法确定方法中的调用约定,因此ArgumentException是更好的选择。

此外,您不应该显式抛出NullReferenceException。 这应该只由CLR抛出。 当明确抛出通常仅由CLR抛出的exception时会发生细微差别。

这也接近于以下的欺骗

  • 扩展方法的ArgumentNullException或NullReferenceException?

为了与Enumerable LINQ运算符保持一致,抛出ArgumentNullException(而不是NullReferenceException)。

我会在TakeRandom方法中进行validation,因为堆栈跟踪将清楚地表明它是TakeRandom,它反对给出一个null参数。

也许我疯了,但因为它是一个参数,我会抛出一个ArgumentNullException:/

一般的经验法则是尽可能抛出派生自System.ApplicationException的exception。 NullReferenceException是框架/ CLR将抛出的东西。

http://msdn.microsoft.com/en-us/library/system.exception(VS.71).aspx

基类Exception下存在两类exception:

从SystemException派生的预定义公共语言运行库exception类。 从ApplicationException派生的用户定义的应用程序exception类。