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类。