只要在项目属性中禁用运行时合同检查,就会为合同类抛出FxCop违规(假设您通过接口实现合同,然后在抽象类中定义合同)。
重新启用运行时合同检查,所有违规都会消失..
这是什么原因?
违反行为:
CA1811 ObjectInvariant似乎没有上游呼叫者
和
CA1033密封MyClassContract
这是没有意义的,因为合同类必须是抽象的。
答案 0 :(得分:6)
好的,我想我明白你的意思了。您有像凯文AccountContracts
这样名为MyClassContract
的班级,其中包含名为ObjectInvariants
而非Invariants
的私有方法:
[ContractClassFor(typeof(IAccount))]
public abstract class MyClassContract : IAccount
{
public abstract double Balance { get; }
void IAccount.Deposit(double amount)
{
Contract.Requires(amount >= 0.0d);
//throw new NotImplementedException();
}
bool IAccount.Withdraw(double amount)
{
Contract.Requires(amount >= 0.0d);
Contract.Requires(amount <= Balance);
throw new NotImplementedException();
}
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(Balance >= 0.0d);
}
}
FxCopy和Code Analysis进行后编译分析。它分析二进制,换句话说,由构建生成的中间语言(IL)。 Code Contracts类似于编译后编织,因为它在二进制文件中生成代码,不仅从您的抽象类MyClassContract
派生,而且至少调用ObjectInvariants
方法一次。
当你&#34;关闭&#34;代码契约,它不再生成此代码,因此FxCop和代码分析不会看到任何来自MyClassContract
的内容,也不会看到任何使用ObjectInvariants
方法的内容,因此会向您发出警告。在MyClassContract
的情况下,由于没有任何东西来源于它,它可以被密封(这有助于编译器在某些情况下稍微优化)以及使类在未来更容易维护(没有 can 源自它,所以你可以更自由地改变它 - 至少这是普遍的共识。)
当然,如果您希望代码保持原样而没有警告,您可以在抑制文件中禁止这些警告。您还可以包含编译器常量并围绕代码以避免在不使用代码协定时进行编译,并在启用代码协定时在构建设置中包含该常量。例如:
#if CODE_CONTRACTS
//...
#endif
创建新的build-config通常是最简单的事情,因为您可以拥有一个特定的构建配置,它可以启用代码契约并在项目构建属性中声明CODE_CONTRACTS
。