contratti di codice .NET: si possono ottenere più di base di questo?
-
12-09-2019 - |
Domanda
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):
string[] source = { "1", "A", "B" };
var sourceObjects = Array.ConvertAll(source, c => new Source(c)).ToArray();
sto ottenendo il messaggio richiede fonte non provata! = Null . Sembra abbastanza ovvio per me che questo non è il caso. Questo è solo un esempio, ovviamente. D'altra parte, alcune cose piuttosto carino sembra funzionare abbastanza bene.
sto usando il 1.2.20518.12 di rilascio (18 maggio). Trovo contratti di codice molto interessante, ma ha chiunque altro ha avuto casi come questo? Lei ritiene che l'implementazione corrente utilizzabile in pratica, o se li si considera puramente accademico, a questo punto?
Ho fatto questo un wiki comunità, ma mi piacerebbe sentire alcune opinioni:)
Soluzione
ha più senso se si dividono le due chiamate su:
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
var sourceObjects = tmp.ToArray();
Ora si punta al ultima linea, come il problema. In altre parole, la chiamata a Array.ConvertAll
sa che source non è nullo, ma la chiamata a ToArray()
non sa che tmp
non sarà nullo.
(Il vostro esempio è anche un po 'di confusione a causa dell'uso del nome source
nel codice sorgente - l'errore sarebbe ancora usare source
anche se aveva chiamato il tuo qualcosa di variabile di completamente diverso, come è riferimento al primo parametro Enumerable.ToArray
.)
In fondo credo che questo sarebbe tutto il lavoro quando Array.ConvertAll ottiene un adeguato postcondition non nullità. 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. E 'importante notare che si tratta di non un problema con il correttore statica in sé.
(In realtà, Array.ConvertAll
non ha una precondizione sia -. Se si imposta la variabile source
su null nel secondo frammento di codice di cui sopra, sarebbe ancora non si lamentano)