2013-02-13 1 views
0

VS2010 ne cesse de me dire qu'un CodeContract.Invariant est faux. Je ne vois pas comment cela peut être le casCodeContracts Invariant is false

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)); 
    } 
} 

L'avertissement est que les deux sont faux invariants, qui ne peut évidemment pas être le cas. J'ai également essayé les deux variantes suivantes.

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

et aussi

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

Il semble que l'invariant est faux, car il est possible pour moi de changer la valeur de la propriété via son setter privé (même si je ne le fais pas.) Est-ce il y a un moyen de faire face à cela? Les propriétés doivent rester propriétés car je suis sérialisation.

+1

Que faire si l'objet est construit 'par son 'private 'constructeur sans arguments? –

+0

Eh bien, ce n'est pas le cas. L'analyseur statique a la capacité de voir qu'aucune partie de la classe n'invoque le constructeur sans paramètre (et n'a pas à chercher dans les autres classes sauf celle-ci). – Alex

+0

Alors, pourquoi cela existe-t-il? –

Répondre

2

Il semble que l'analyseur statique ne voit pas que le constructeur sans paramètre n'est jamais invoqué. Peut-être que son existence est suffisante pour interroger votre invariant.

Pouvez-vous l'enlever complètement? Si vous avez déjà un constructeur, pourquoi avez-vous besoin d'un constructeur privé sans paramètre?

+0

Je migrais des structs vers les classes. C'était le problème, alors merci! –

0

Je m'attendrais à ce que le constructeur par défaut privé soit la source de l'avertissement, puisque l'exécution de cette commande violerait l'invariant. Toutefois, puisque vous avez défini un constructeur, rien ne vous empêche de supprimer le constructeur par défaut. Si vous définissez au moins un constructeur, le compilateur n'émettra pas de constructeur par défaut en votre nom et puisque vous n'utilisez jamais le constructeur par défaut, il n'y a aucune raison de l'avoir