Search code examples
c#code-contracts

How to not duplicate Code Contracts checks?


I have static class which contains methods with same signatures.

static class SomeClass
{
    static void SomeMethod(int param)
    {
        Contract.Requires<ArgumentException>(param != 0);
        // some code
    }

    static void SomeMethod2(int param)
    {
        Contract.Requires<ArgumentException>(param != 0);
        // some code
    }
}

Is there any way to not duplicate CodeContract checks in this methods?


Solution

  • You can use a contract abbreviator. But personally I would not do it for this kind of simple check. Here's an example for an abbreviator we use:

    public static class ContractEx
    {
        [ContractAbbreviator]
        public static void StringNullOrEmpty(string s, string parameterName)
        {
            Contract.Requires<ArgumentNullException>(s != null, parameterName);
            Contract.Requires<ArgumentException>(s.Length != 0, parameterName);
            Contract.Requires(!String.IsNullOrEmpty(s));  // required for static code analysis
        }
    }
    

    Usage:

    void SomeMethod(string foo)
    {
        ContractEx.StringNullOrEmpty(foo, "foo");
    }
    

    Note this has the distinct disadvantage of having to specify the parameter name yourself. You can omit it, but then the contracts rewriter would emit an exception with s != null as the condition that failed, which makes no sense for an argument exception.

    Abbreviators usually make more sense as instance methods that check the state of a class. For example (from MSDN):

    [ContractAbbreviator]
    private void DataAndStateUnchanged() 
    {
       Contract.Ensures(this.State == Contract.OldValue(this.State));
       Contract.Ensures(this.Data == Contract.OldValue(this.Data));
    }