我正在玩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检查全部空值对性能和代码膨胀的原因没有那么大的吸引力,但我想听听其他人不得不说的话....
答案 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。”
另外,请检查语法并阅读有关您应该传递给ArgumentNullException构造函数的信息。
throw new ArgumentNullException("its null and this shouldn't happen");
这是不对的。
throw new ArgumentNullException("VariableName");
这是对的。