假设您有一个现有的大型项目,并且希望在其中集成代码合同。现有代码使用if-null-then-throw逻辑。对于给定的条件,文档建议将汇编模式设置为Custom Argument Validation。
我有以下课程:
class A
{
protected virtual void Foo(int a, int b)
{
if (a == null)
throw new ArgumentNullException(a);
if (b == null)
throw new ArgumentNullException(b);
Contract.EndContractBlock();
}
}
class B : A
{
protected override void Foo (int a, int b)
{
// some stuff
base.Foo(a, b);
}
}
编译时,我收到以下警告:
警告CC1055:方法'B.Foo(int,int)'应该包含自定义 'Requires(a!= null)'的参数验证 因为它覆盖'A.Foo(int,int)',这表明它确实如此。如果你不这样做 想在此程序集中使用自定义参数验证,请更改 装配模式为'标准合同要求'。
我不想重复每个重写方法的前提条件!有办法吗?
答案 0 :(得分:4)
如果您使用Contract.Requires()
而非Contract.EndContractBlock()
,则可以正常使用。
下面引用的手册中有一节建议在方法覆盖中添加[SuppressMessage]
属性。
来自Code Contracts user manual第22页第5.2.3节。
将检查委派给其他方法
假设您的代码模式类似于以下代码:
public class Base { public virtual void Compute(string data) { if (data == null) throw new ArgumentNullException(...); Contract.EndContractBlock(); ... } } public class Derived : Base { public override void Compute(string data) { base.Compute(data); ... } }
然后工具将发出警告CC1055,其中包含以下形式的消息:
方法'Derived.Compute'应包含自定义参数验证 '覆盖时需要(ArgumentNullException)(data!= null)' 'Base.Compute'暗示它确实如此。
在这种情况下,警告没有帮助,因为实施 Derived.Compute将参数验证委托给另一个 方法(在这种情况下是基本方法)。为了避免这种警告 没有重复验证的情况,你可以添加一个 SuppressMessage属性为方法:
public class Derived : Base { [SuppressMessage("Microsoft.Contracts", "CC1055", Justification = "Validation performed in base method")] public override void Compute(string data) { base.Compute(data); ... } }