Scrivere codice a prova di bug con i Code Contracts

di Cristian Civera, in .NET Framework 4.0,

Il .NET Framework è una tecnologia che basa il suo funzionamento sugli oggetti, e di conseguenza i linguaggi che è possibile utilizzare, come C# e VB, sfruttano classi, oggetti, incapsulamento, ereditarietà e poliformismo per la produzione di codice IL nella fase di compilazione.

Questi linguaggi ad alto livello, sebbene lavorino in modo tipizzato e godano della compilazione per effettuare un controllo sintattico e di integrità dei tipi, non mettono al riparo da possibili errori che possono avvenire a runtime a causa di riferimenti nulli, operazioni aritmetiche, o in generale per situazioni non previste. Le variabili, come tali, creano una casistica che è difficile prevedere, mentre non è detto che tutto il codice scritto sia dello stesso sviluppatore che conosce cosa è possibile fare. Una classe infatti può essere utilizzata in modo improprio ed è spesso necessario istruire chi la utilizzata, soprattutto se questa fa parte di una libreria sfruttata da più parti.

Perché i code contracts

Per risolvere questo tipo di problematica vi sono molteplici vie che si possono adottare e anzi, andrebbero adottate interamente. Prima tra tutte è la preparazione e la consultazione della documentazione, la quale ci può indicare come utilizzare una classe, con quali parametri e quali sono le eccezioni che possono essere lanciate. Questo però non basta, perché non si ha nessun controllo effettivo del codice, ne è garantita la qualità dello stesso. Il testing però viene in aiuto permettendo di provare in modo atomico parti del codice e verificare che risponda nel modo previsto, a seconda di alcune condizioni preparate appositamente.

Fare testing però non è semplice e purtroppo spesso non è concesso al team di sviluppo il tempo e le risorse necessarie per scrivere test approfonditi o neanche in modo essenziale. I code contracts vengono aiuto portando uno strumento che mira a rendere più robusto il codice assicurando la validità dei parametri e del risultato di una funzione, o lo stato corretto di un oggetto, permettendo inoltre di avere informazioni automatizzate sul suo utilizzo.

Per usufruire di questo strumento prima di tutto è necessario installarlo scaricando la versione Standard (per Visual Studio versioni Standard/Express) o Premium (per Visual Studio Premium o Ultimate) dalla sito dedicato. Al termine del setup si consiglia inoltre di installare le estensioni per Visual Studio 2010, disponibili al medesimo indirizzo o attraverso l'extension manager di Visual Studio cercando l'estensione "Code Contracts Editor Extensions".

Terminata l'installazione, l'ambiente di Visual Studio dispone di una tab in più nelle proprietà dei progetti e alcune nuove caratteristiche dell'intellisense, affrontate nel corso dell'articolo. Queste feature però non sono il fulcro dei code contract la cui utilità deriva dalla possibilità di scrivere supposizioni attraverso le pre e le post condizioni.

Un primo esempio: validazione dei parametri

Introducendo i code contract si è detto che essi mirano a rendere più robusto il codice scritto. Molti degli errori che possono colpire il codice sono dovuti infatti ai parametri di costruttori, metodi e funzioni perciò è buona norma validarli prima di utilizzarli.

Ad esempio, una ipotetica funzione ToFirstUpperCase che riceve la stringa da formattare dovrebbe essere dichiarata e iniziare nel seguente modo:

string ToFirstUpperCase(string s)
{
  if (s == null)
    throw new ArgumentNullException("s");
  ...
}

Questo controllo, che la BCL e l'intero .NET Framework in genere implementano, presenta due difetti:

  • E' verboso e ripetitivo, perciò spesso si finisce con il non farlo;
  • Non permette di conoscere dall'esterno quali sono le condizioni valide per chiamare la funzione se non consultando la documentazione (sempre se è stata scritta).

I code contract vengono quindi in aiuto facilitando questo tipo di operazioni, fornendo una classe di nome Contract avente metodi statici il cui scopo è fare supposizioni. Questa classe è contenuta nell'assembly mscorlib (assembly base del .NET Framework) della versione 4.0, o nell'assembly Microsoft.Contracts.dll che è possibile trovare nella cartella %ProgramFiles\Microsoft\Contracts\Contracts a seconda del framework (3.5, Silverlight) che si sta utilizzando.

Grazie a questa classe il codice prima citato può essere riscritto in questo modo:

string ToFirstUpperCase(string s)
{
  Contract.Requires<ArgumentNullException>(s != null);
  ...
}

Tramite il metodo statico Required si richiede che un'espressione sia valida e in caso non lo sia che venga lanciata un'eccezione di tipo ArgumentNullException. Per far sì che questa validazione funzioni occorre aprire le proprietà del progetto su cui si sta lavorando e posizionarsi sulla nuova tab "Code Contracts". In questa scheda occorre abilitare l'opzione "Perform runtime contract checking".

A questo punto è possibile provare a chiamare la funzione ToFirstUpperCase passando null e ottenere un'eccezione, così come si aspetta.

5 pagine in totale: 1 2 3 4 5
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Top Ten Articoli

Articoli via e-mail

Iscriviti alla nostra newsletter nuoviarticoli per ricevere via e-mail le notifiche!

In primo piano

I più letti di oggi

In evidenza

Misc