Search code examples
c#.netcode-contracts

CodeContracts Invariant is false


VS2010 keeps telling me that a CodeContract.Invariant is false. I can't see how this can possibly be the case

public class BankAccountIdentifierDefinitionVariation_CreateCommandArgs : ValidatedCommandArgs
{
    public string IdentifierCode {get; private set; }
    public string CountryCode {get; private set; }
    public Ems.Infrastructure.Validation.StringValidator Validator {get; private set; }

    private BankAccountIdentifierDefinitionVariation_CreateCommandArgs()
        : base() { }

    public BankAccountIdentifierDefinitionVariation_CreateCommandArgs(
        string identifierCode,
        string countryCode,
        Ems.Infrastructure.Validation.StringValidator validator)
    {
        Contract.Requires(!string.IsNullOrEmpty(identifierCode));
        Contract.Requires(!string.IsNullOrEmpty(countryCode));
        Contract.Ensures(!string.IsNullOrEmpty(this.IdentifierCode));
        Contract.Ensures(!string.IsNullOrEmpty(this.CountryCode));

        this.IdentifierCode = identifierCode;
        this.CountryCode = countryCode;
    }

    [ContractInvariantMethod]
    void ContractInvariants()
    {
        Contract.Invariant(!string.IsNullOrEmpty(IdentifierCode));
        Contract.Invariant(!string.IsNullOrEmpty(CountryCode));
    }
}

The warning is that both invariants are false, which obviously cannot be the case. I have also tried the two following variations.

Contract.Ensures(!string.IsNullOrEmpty(this.IdentifierCode);
if (string.IsNullOrEmpty(identifierCode)) throw new ArgumentNullException...
this.IdentifierCode = identifierCode;

and also

Contract.Ensures(!string.IsNullOrEmpty(this.IdentifierCode));
this.IdentifierCode = identifierCode;
if (string.IsNullOrEmpty(this.IdentifierCode)) throw new ArgumentNullException...

It looks as if the invariant is false because it is possible for me to change the value of the property via its private setter (even though I do not.) Is there a way to deal with this? The properties must remain properties because I am serializing.


Solution

  • It seems that the static analyzer fails to see that the parameterless constructor is never invoked. Maybe its existance is enough to question your invariant.

    Can you remove it altogether? If you already have a constructor, why do you need a private parameterless one?