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

时间:2009-04-25 04:17:54

标签: c# exception extension-methods argument-validation

假设我有一个扩展方法

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

要验证参数e,我应该:

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

什么是共识?

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

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

3 个答案:

答案 0 :(得分:10)

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

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

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

这也接近以下

的欺骗

答案 1 :(得分:4)

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

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

答案 2 :(得分:1)

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

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

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

  

存在两类例外   在基类Exception下:

     

预定义的通用语言   从中派生的运行时异常类   SystemException的。用户定义的   应用程序异常类派生   来自ApplicationException。

相关问题