Se il controllo statico Code Contracts essere in grado di controllare l'aritmetica legato?
-
12-09-2019 - |
Domanda
(anche rel="noreferrer"> MSDN -. ma questo non ottiene molto traffico, per quanto posso vedere)
Ho cercato di fornire un esempio di Assert
e Assume
. Ecco il codice che ho:
public static int RollDice(Random rng)
{
Contract.Ensures(Contract.Result<int>() >= 2 &&
Contract.Result<int>() <= 12);
if (rng == null)
{
rng = new Random();
}
Contract.Assert(rng != null);
int firstRoll = rng.Next(1, 7);
Contract.Assume(firstRoll >= 1 && firstRoll <= 6);
int secondRoll = rng.Next(1, 7);
Contract.Assume(secondRoll >= 1 && secondRoll <= 6);
return firstRoll + secondRoll;
}
(La struttura di essere in grado di passare in riferimento null invece di un riferimento Random
esistente è puramente pedagogica, ovviamente.)
Avevo sperato che, se il correttore sapeva che firstRoll
e secondRoll
erano ciascuna nella gamma [1, 6]
, sarebbe in grado di capire che la somma era nella gamma [2, 12]
.
Si tratta di una speranza irragionevole? Mi rendo conto che è una faccenda complicata, lavorando esattamente ciò che potrebbe accadere ... ma speravo l'ispettore sarebbe abbastanza intelligente:)
Se questo non è supportato ora, qualcuno qui sa se è probabile che sia supportato nel prossimo futuro-ish?
EDIT: ora ho scoperto che ci sono opzioni molto complicato per l'aritmetica nel correttore statica. Utilizzando la casella di testo "avanzata" che io possa provare da Visual Studio, ma non c'è alcuna spiegazione decente di quello che fanno, per quanto posso dire.
Soluzione
Ho avuto una risposta sul forum di MSDN. Si scopre che ero quasi lì. In sostanza il controllo statico funziona meglio se si divide out "e-ed" contratti. Quindi, se cambiamo il codice a questo:
public static int RollDice(Random rng)
{
Contract.Ensures(Contract.Result<int>() >= 2);
Contract.Ensures(Contract.Result<int>() <= 12);
if (rng == null)
{
rng = new Random();
}
Contract.Assert(rng != null);
int firstRoll = rng.Next(1, 7);
Contract.Assume(firstRoll >= 1);
Contract.Assume(firstRoll <= 6);
int secondRoll = rng.Next(1, 7);
Contract.Assume(secondRoll >= 1);
Contract.Assume(secondRoll <= 6);
return firstRoll + secondRoll;
}
che funziona senza problemi. Significa anche l'esempio è ancora più utile, come evidenzia il punto stesso che il correttore non lavoro meglio con contratti separati fuori.
Altri suggerimenti
Non so circa la MS Contratti strumento Controllo, ma l'analisi Range è una tecnica di analisi statica di serie; è ampiamente usato in strumenti di analisi statica commerciali per verificare che le espressioni pedice sono legali.
MS La ricerca ha un buon track record in questo tipo di analisi statica, e quindi mi aspetto di fare questo tipo di analisi gamma ad essere un obiettivo dei contratti Checker, anche se non attualmente selezionata.