Sto provando a dimostrare le invarianti nei Contratti di codice e ho pensato di fornire un esempio di elenco ordinato di stringhe. Mantiene una matrice internamente, con spazio libero per aggiunte ecc. - come List<T>
, in pratica. Quando è necessario aggiungere un elemento, inserisce nella matrice, ecc ho pensato che avevo tre invarianti:Quanto posso essere libero nel codice in un oggetto invariante?
- Il conteggio deve essere sensibile: non negativi e al più grande come la dimensione del buffer
- Tutto in parte non utilizzata del buffer dovrebbe essere nullo
- Ogni elemento della parte usata del tampone dovrebbe essere almeno come "grande" come la voce prima che
Ora, ho cercato di implementalo in questo modo:
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(count >= 0 && count <= buffer.Length);
for (int i = count; i < buffer.Length; i++)
{
Contract.Invariant(buffer[i] == null);
}
for (int i = 1; i < count; i++)
{
Contract.Invariant(string.Compare(buffer[i], buffer[i - 1]) >= 0);
}
}
Sfortunatamente, ccrewrite
si incasina negli anelli.
La documentazione dell'utente dice che il metodo dovrebbe essere solo una serie di chiamate a Contract.Invariant
. Devo davvero riscrivere il codice come qualcosa di simile?
Contract.Invariant(count >= 0 && count <= buffer.Length);
Contract.Invariant(Contract.ForAll
(count, buffer.Length, i => buffer[i] == null));
Contract.Invariant(Contract.ForAll
(1, count, i => string.Compare(buffer[i], buffer[i - 1]) >= 0));
Questo è un po 'brutto, anche se funziona. (È molto meglio del mio precedente tentativo, intendiamoci).
Le mie aspettative sono irragionevoli? I miei invarianti sono irragionevoli?
(anche chiesto come question in the Code Contracts forum. Io aggiungo risposte rilevanti qui me stesso.)
Apparentemente, non puoi essere libero come il ciclo si srotola./rimshot –
La cosa bizzarra è che il primo * ciclo * va bene ... ma il secondo no. Potrebbe rivelarsi un bug in ccrewrite, ovviamente. –
(Sospetto che stia catturando tutto il codice prima della chiamata a Contract.Invariant ...) –