另一个人问了类似的问题,但我不清楚答案。
我们的项目中有很多参数验证代码。它们大多只是公共方法中的空参数检查:
if (param == null)
{
throw new ArgumentNullException("param");
}
这些检查不是规范的一部分。它们的主要用途是在发生编程错误时获得更明智的堆栈转储。如果没有完成这样一个简单的检查,您最终可能会在堆栈深处的十级中,在某个其他库中间的随机位置中使用NullReferenceException
. 这使得整个回溯到根本原因的过程更长。验证检查在语义上是清晰的,可以让您更早地发现问题。
由于我们经常这样做,因此我们一直在寻找更短的方法来进行此类检查。如:
ArgumentHelper.ThrowIfNull(param, "param");
或类似的语法。我们想基本上避免开销。语法使if-throw
代码不必要地长。
当我尝试使用这种语法时,我注意到我正在收敛到类似的语法,比如断言和代码契约。代码契约非常有吸引力,因为它可以在开发周期的早期进行静态分析和捕捉错误。
但是,据我了解,代码合同并非旨在解决“输入验证”问题或任何类型的验证问题。因为它引发的异常并不意味着被捕获。它们也不是为了使调试更容易,因为默认行为是从发布版本中的此类检查中剥离代码。重写器似乎只是围绕它进行破解,而且它的性能也不是很好。
我从“静态验证”和“参数验证”中了解到的目标不同,因此它们不能互换。然而,Code.Contracts
在我的序言中使用if-then-throw
s 一开始听起来很自然,我想知道我是不是有什么问题。
我的问题是:使用代码合同进行参数验证是否有效?是否有一个明确的问题我可以向任何验证代码提出并提出一个答案,例如:“是的,您可以使用代码合同来检查这个”和“不,您不能使用代码合同来检查那个”?我该如何区分?
我想出了“如果我删除合同声明,该功能会继续正常工作吗?”。这是一个正确的方法吗?