是否允许NullReferenceException发生坏事?

时间:2011-03-17 12:07:14

标签: c# nullreferenceexception pex

我正在玩Pex和Moles,在运行Pex之后发现几乎Pex所说的所有测试都失败了,因为NullReferenceExceptions是“允许的”。阅读Pex文档,我发现了以下内容:

  

如果更高级别的组件通过   格式错误的数据到较低级别   组件,其中较低级别   组件拒绝,然后是   应该是更高级别的组件   在第一次被禁止这样做   的地方。

所以上面的建议是我们应该在使用类似的东西调用其他方法/类之前测试空值。

if(foo == null)
   throw new ArgumentNullException("its null and this shouldn't happen")
else
   Bar(foo); //won't get a null reference exception here because we checked first...

IMHO检查全部空值对性能和代码膨胀的原因没有那么大的吸引力,但我想听听其他人不得不说的话....

4 个答案:

答案 0 :(得分:9)

是的,您应该在使用它们之前验证您的参数,IMO。

使用意外的 null值时,应发生

NullReferenceException。它永远不应该被明确抛出,并且表示在最终抛出它的方法级别或者被调用的东西上存在问题。

ArgumentNullException表示调用堆栈中早期方法中的错误比抛出它的方法中的错误。 (通常,但并非总是如此,直接来电者。)

越早抛出表示问题的异常,就越容易确定空值首先在中出现的位置“不良数据”的可能性越小其他地方令人讨厌的影响(例如,在意识到实际上数据为空之前,覆盖准备将数据写入其中的文件)。

如果您对如何调用内部或私有方法有信心,那么不执行检查那里可能是合适的,但对于公共方法,我认为参数验证几乎总是合适的。< / p>

答案 1 :(得分:3)

是的,我同意。 NullReferenceException是尝试在作为空引用的变量上调用成员的结果。这意味着没有安全防护来验证调用该成员是合法的操作,这在我看来是件坏事。你总是不信任输入并确认你使用是安全的。

答案 2 :(得分:1)

当参数传递给公开服务的函数时,检查NULL是一个好习惯。其余的NULL检查是常识,但它很有用,你基本上可以使用辅助方法来完成它。

最讨厌的NULL检查是使用字符串。它们可能非常讨厌,但我使用扩展方法来克服这个问题:

public static class StringExtensions
{
    public static string NullSafe(this string s)
    {
        return s ?? string.Empty;
    }
}

所以你可以使用:

myString.NullSafe().ToUpper()

答案 3 :(得分:1)

即使从简单的诊断角度来看,您可以获得更多有关的信息 - NullReferenceException ArguementNullException

更进一步,将堆栈跟踪从图片中取出。你的两条消息可能是:

<强>的NullReferenceException: “对象引用未设置为对象的实例。”

  • 某些东西是空的,某处,我可能没想到它。
  • 我可能需要调试才能找到错误。

<强> ArguementNullException: “System.ArgumentNullException:MyVariable不能为null。”

  • 我知道null被传递给方法。
  • 根据变量名称,我可以将其缩小为一组较小的可能方法
  • 我仍然可能需要调试,但我应该能够知道一些断点的常用位置。

另外,请检查语法并阅读有关您应该传递给ArgumentNullException构造函数的信息。

throw new ArgumentNullException("its null and this shouldn't happen");

这是不对的。

throw new ArgumentNullException("VariableName");

这是对的。