Ma classe a une propriété qui est initialisée dans le constructeur et qui n'est jamais censée changer. Les méthodes tout autour de mon code acceptent cette classe comme un paramètre et s'appuient sur cette propriété pour satisfaire une certaine condition.Comment indiquer au vérificateur statique qu'une propriété ne change jamais lorsqu'elle n'est pas prouvée?
Le point clé est qu'il est vraiment indémontrable que la propriété ne change jamais. Je peux personnellement "jurer" qu'il ne change jamais (et j'ai aussi des tests unitaires pour cela), mais cela ne peut pas être prouvé formellement (ou du moins je le pense).
Prenons l'exemple suivant réduit:
public class ConstantPoperty
{
public class SomeClass
{
public int SomeProp {
get { return GetSomePropThroughUnprovableMechanism(); }
}
public SomeClass(int i)
{
SetSomePropThroughUnprovableMechanism(i);
}
}
public void Method(SomeClass c)
{
Contract.Requires(c != null);
Contract.Requires(c.SomeProp == 5);
}
public void FalsePositive()
{
SomeClass c = new SomeClass(5);
if (c.SomeProp != 5) return;
Method(c);
Method(c); // unproven requires: c.SomeProp == 5
}
}
Notez que le premier appel à Method()
obtenir un OK du vérificateur, puisque je l'ai vérifié juste avant que la condition qu'il soit satisfait.
Toutefois, le deuxième appel reçoit un avertissement non prouvé. Ma supposition est, le vérificateur suppose que le premier appel à Method(c)
pourrait changer c.SomeProp
de sorte qu'il ne satisfera plus la condition.
De là, je peux en déduire deux solutions de contournement possibles, ni dont je considère acceptable:
Ajouter
Contract.Ensures(c.SomeProp == Contract.OldValue(c.SomeProp))
-Method
, ainsi que toute autre méthode qui accepte des arguments de typeSomeClass
.
On peut facilement voir à quel point c'est absolument ridicule.Ajoutez un contrôle redondant pour
c.SomeProp == 5
avant le deuxième appel àMethod(c)
.
Bien que ce soit moins ridicule que la première option, elle est également inacceptable, car en plus d'encombrer le code, elle aura également une pénalité de performance (une telle vérification ne sera pas optimisée).
La solution idéale serait de convaincre en quelque sorte le vérificateur que SomeProp
est censé ne jamais changer après la construction, mais je ne pouvais pas trouver un moyen de le faire. Ou peut-être qu'il me manque quelque chose d'évident ici?
Ah! Ok, je vois mon erreur maintenant: j'ai incorrectement réduit l'exemple. Le point clé ici est que la nature immuable de la propriété ne peut pas être prouvée formellement. Ce n'est pas une propriété simple et directe, mais il y a un mécanisme de stockage magique derrière. Je sais que cela ne change en effet jamais (et j'ai des tests unitaires pour ça), mais je ne sais pas comment convaincre le vérificateur. J'ai mis à jour le message original pour refléter cela. Désolé pour la confusion. –