Reputation: 1665
Suppose you have an existing large project and you want to integrate Code Contracts in it. The existing code uses if-null-then-throw logic. For the given conditions, the documentation suggests to set the assembly mode to Custom Argument Validation.
I have the following classes:
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);
}
}
When I compile I get the following warning:
warning CC1055: Method 'B.Foo(int, int)' should contain custom argument validation for 'Requires(a != null)' as it overrides 'A.Foo(int,int)' which suggests it does. If you don't want to use custom argument validation in this assembly, change the assembly mode to 'Standard Contract Requires'.
I don't want to repeat the preconditions on every overridden method! Is there a way around it?
Upvotes: 1
Views: 969
Reputation: 11326
It works fine if you use Contract.Requires()
instead of Contract.EndContractBlock()
.
There is a section in the manual quoted below which suggests adding a [SuppressMessage]
attribute to the method override.
From the Code Contracts user manual p.22 section 5.2.3.
Delegating Checks to Other Methods
Suppose you have a code pattern similar to the following code:
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); ... } }
Then the tools will issue warning CC1055 with a message of the form:
Method ’Derived.Compute’ should contain custom argument validation for ' Requires (ArgumentNullException)(data ! = null)' as it overrides 'Base.Compute' which suggests it does.
In this situation, the warning is not helpful, as the implementation of Derived.Compute delegates the parameter validation to another method (in this case the base method). To avoid the warning in this situation without repeating the validation, you can add a SuppressMessage attribute to the method:
public class Derived : Base { [SuppressMessage("Microsoft.Contracts", "CC1055", Justification = "Validation performed in base method")] public override void Compute(string data) { base.Compute(data); ... } }
Upvotes: 4