另一个人asked a similar question但答案并不清楚。代码合同可以取代参数验证吗?
我们的项目中有很多参数验证代码。他们大多是零参数检查公共方法只:
if (param == null)
{
throw new ArgumentNullException("param");
}
这些检查不是规范的一部分。它们的主要用途是在编程错误的情况下获得更安全的堆栈转储。如果这样一个简单的检查没有完成,你可以在一个其他图书馆中间的一个随机点中以NullReferenceException
结束十个深度。这使整个回溯到根本原因过程更长。验证检查在语义上是清晰的,可以让您更早地发现问题。
既然我们这么做了,我们一直在寻找更短的方法来做这样的检查。如:
ArgumentHelper.ThrowIfNull(param, "param");
或类似的语法。我们希望避免基本上的开销。 if-throw
语法使得代码不必要的很长。
当我试验这样的语法时,我注意到我收敛到类似于断言和代码合同的语法。代码合同非常有吸引力,因为在开发周期的早期就有可能进行静态分析和捕获错误。
然而,据我所知代码合同并没有设计来补救“输入验证”问题或任何类型的验证问题。 Because the exceptions raised by it are not meant to be caught。他们不是为了使调试更容易,因为默认行为是剥离发布版本中的这些检查的代码。 The rewriter just seems like a hack around it and it's not very performant either。
我从所有的理解是“静态验证”和“参数验证”有不同的目标,因此它们不能互换。然而,使用Code.Contracts
作为我的开场白if-then-throw
听起来很自然,我开始不知道自己是否有错。
我的问题是:使用代码合同进行参数验证有效吗?是否有一个明确的问题,我可以问任何验证代码,并提出一个答案,如:“是的,你可以使用代码合同来检查这个”和“不,你不能使用代码合同来检查”?我如何做出区分?
我想出了“如果我删除了合同声明,该功能是否能正常工作?”。这是一个正确的方法吗?
还检查了其抛出异常,并提供代码契约在一个非常干净的方式我的扩展方法:http://blog.rsuter.com/elegant-method-parameter-validation- with-code-contracts-support/ –
@RicoSuter您的评论仍需要启用代码合同的运行时检查。看到我的答案为什么这是不好的:http://stackoverflow.com/a/25700857/54937 –
不,你有合同和通常的抛出异常,即使运行时验证被禁用,抛出异常... –