2009-08-09 16 views
5

Stavo solo scherzare per rispondere alla domanda di qualcuno qui su Stack Overflow, quando ho notato un avvertimento verifica statica da dentro la mia Visual Studio (2008):Contratti di codice .NET: può essere più basilare di questo?

string[] source = { "1", "A", "B" }; 
var sourceObjects = Array.ConvertAll(source, c => new Source(c)).ToArray(); 

sto ottenendo il messaggio richiede fonte non provata! = null. Mi sembra abbastanza ovvio che non sia così. Questo è solo un esempio, naturalmente. Dall'altra parte, alcune cose piuttosto eleganti sembrano funzionare abbastanza bene.

Sto usando la versione 1.2.20518.12 (18 maggio). Trovo che i contratti di codice siano molto interessanti, ma qualcun altro ha avuto casi come questo? Ritieni che l'implementazione corrente sia utilizzabile nella pratica o li considereresti puramente accademici a questo punto?

Ho fatto questo un wiki comunità, ma mi piacerebbe sentire alcune opinioni :)

risposta

16

ha più senso se si dividono le due chiamate up:

string[] source = { "1", "A", "B" }; 
var tmp = Array.ConvertAll(source, c => new Source(c)); 
var sourceObjects = tmp.ToArray(); 

Ora punta alla riga last come il problema. In altre parole, la chiamata a Array.ConvertAll sa che la fonte non è nullo, ma la chiamata a ToArray() non sa che tmp non sarà nullo.

(Il tuo esempio è anche leggermente confuso a causa dell'uso del nome source nel codice sorgente - l'errore potrebbe comunque utilizzare source anche se hai chiamato la tua variabile qualcosa di completamente diverso, in quanto si riferisce al primo parametro in Enumerable.ToArray.)

Fondamentalmente credo che tutto ciò funzionerebbe quando Array.ConvertAll otterrà un postcondition appropriato non nullo. Fino ad allora, questo farà il trucco:

string[] source = { "1", "A", "B" }; 
var tmp = Array.ConvertAll(source, c => new Source(c)); 
Contract.Assume(tmp != null); 
var sourceObjects = tmp.ToArray(); 

Sono d'accordo questo genere di cose è fastidioso, ma sono sicuro che migliorerà rapidamente MS aggiunge sempre più contratti nel BCL. È importante notare che è non un problema con il controllo statico stesso.

(In realtà, Array.ConvertAll non hai precondizione o - se si imposta la variabile source su null nel secondo frammento di codice di cui sopra, ancora sarebbe non si lamentano.)

+1

già attraverso la scrittura il capitolo contratti? :) –

+1

Quasi lì, sì :) Sono rimasto molto colpito da questo, a dire il vero. –

+1

Non ho ancora inserito il lavoro interiore, ma come sono definite le precondizioni e le postcondizioni per i metodi già presenti nelle versioni esistenti della libreria della classe base? Immagino che abbiano appena abbandonato qualsivoglia ccrewrite di solito genera nella distribuzione? – Thorarin

Problemi correlati