1

假设您有一个现有的大型项目,并且想要在其中集成代码合同。现有代码使用 if-null-then-throw 逻辑。对于给定的条件,文档建议将组装模式设置为自定义参数验证。

我有以下课程:

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)' 这表明它确实如此。如果您不想在此程序集中使用自定义参数验证,请将程序集模式更改为“标准合同要求”。

我不想在每个被覆盖的方法上重复前提条件!有办法解决吗?

4

1 回答 1

4

如果您使用Contract.Requires()而不是Contract.EndContractBlock().

下面引用的手册中有一节建议向[SuppressMessage]方法覆盖添加一个属性。

来自Code Contracts 用户手册第 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”应包含“Requires (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);
        ...
    }
}
于 2012-05-23T08:18:31.660 回答