我看过代码,其中包括Contract.Assert
,
Contract.Assert(t != null);
使用Contract.Assert
会对我的生产代码产生负面影响吗?
我看过代码,其中包括Contract.Assert
,
Contract.Assert(t != null);
使用Contract.Assert
会对我的生产代码产生负面影响吗?
根据第 11 页的手册,它们仅在DEBUG
定义符号时才包含在您的程序集中(当然,包括调试版本,但不包括发布版本(默认情况下))。
除了运行时的好处之外Contract.Assert
,您还可以考虑在调用未定义合同的遗留代码时使用Contract.Assume
(手册第 2.5 页第 11 页)的替代方法,并且如果您希望将静态警告级别提高到高(例如静态检查级别more warnings
或all warnings
- 级别 3+ - 并Show Assumptions
打开)。
Contract.Assume
为您提供与 相同的运行时优势Contract.Assert
,但也抑制了由于遗留程序集而无法证明的静态检查。
例如,在下面的代码中,启用静态检查并将警告设置为 3 级时,会warning : CodeContracts: requires unproven: someString != null
在检查合同时给出MethodDoesNotAllowNull
var aString = Legacy.MethodWithNoContract();
MethodDoesNotAllowNull(aString);
private void MethodDoesNotAllowNull(string someString)
{
Contract.Requires(someString != null);
}
使用旧版汇编代码:
public static string MethodWithNoContract()
{
return "I'm not really null :)";
}
Assume
抑制警告(但在调试版本中提供运行时断言优势):
var aString = LegacyAssembly.LegacyMethodWithNoContract();
Contract.Assume(aString != null);
MethodDoesNotAllowNull(aString);
这样,您仍然可以获得调试版本的empirical
运行时优势。Contract.Assert
至于好的实践,最好有一组好的单元测试。那么代码合约就没有那么必要了。它们可能会有所帮助,但不太重要。