在继承链中重复代码契约要求?

时间:2012-05-22 21:31:20

标签: c# .net-4.0 code-contracts

假设您有一个现有的大型项目,并且希望在其中集成代码合同。现有代码使用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)',这表明它确实如此。如果你不这样做   想在此程序集中使用自定义参数验证,请更改   装配模式为'标准合同要求'。

我不想重复每个重写方法的前提条件!有办法吗?

1 个答案:

答案 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);
        ...
    }
}