Sono rimasto davvero affascinato dai contratti di codice introdotti in .NET 4 (anche se con l'aiuto di DevLabs). Ma una bella stampa mi ha raffreddato un po '. Ecco cosa dice:Contratti di codice - bello, al limite, ma non pronto per la prima serata?
- Attualmente non vi è alcuna soluzione al problema quando le postcondizioni vengono richiamate al di fuori del blocco in un metodo thread-safe eccetto per non utilizzarle.
- .NET si basa su un programma di reindirizzamento binario, rendendo così la costruzione più lenta.
- L'utilizzo di contratti di codice può inoltre causare un problema di prestazioni in fase di esecuzione.
- Non può essere utilizzato per i controlli di sicurezza perché possono essere aggirati in fase di esecuzione gestendo l'evento ContractFailed.
Il più grande per me è il primo. Non so se qualcuno scriva più app a thread singolo. Quindi se i contratti di codice non sono in grado di supportare il multithreading, non li vedo molto. O forse non dovrei sottolinearlo troppo perché le postcondizioni servono a far valere gli interni del metodo stesso, che può essere testato unitamente.
BTW, non ho trovato nulla e non ho provato a smontare il mio codice per vedere dove sono state iniettate le precondizioni. Suppongo in un metodo semplice quando lock() va per primo, è semplice iniettare i controlli subito dopo, ma con un metodo piuttosto complicato, quando il blocco avviene da qualche parte nel mezzo, potrebbe essere un problema. O se vengono utilizzati altri meccanismi diversi da lock().
Sono d'accordo quando si tratta di classi apolidi. Ma quando si tratta di gestire lo stato, le classi devono essere thread-safe. Faccio del mio meglio per minimizzare il numero di loro però. Sul lato, potrei pensare di più in bianco e nero o piuttosto tutto o niente approccio - perché usare i contratti di codice in alcuni punti e non in altri a causa dei loro limiti. – Schultz9999
@ Schultz9999: No, solo le classi stateful * che vengono utilizzate simultaneamente da più thread * devono occuparsene. Va bene se * o * una classe viene utilizzata da un thread solo per un'intera richiesta (ad esempio, gli StringBuilder di solito non vengono utilizzati tra i thread) * o * vengono utilizzati solo da un thread alla volta, con opportune barriere di memoria per consistenza. Per quanto riguarda la tua seconda domanda: usa i contratti di codice solo per * alcuni * del tuo codice se così facendo rende il tuo codice più chiaro o più affidabile, in pratica. Alcuni codici sono difficili/impossibili da testare unitamente - ma scrivo ancora test dove posso ... è lo stesso qui. –
Sono d'accordo con le tue risposte su come scrivere codice. Forse lo stesso oggetto di stato può fornire un modo per mantenere i thread interni sicuri, mentre i gestori potrebbero non preoccuparsi del blocco, consentendo in tal modo al rewriter di riorganizzare il codice come previsto. Questo aiuta a evitare il problema, ma rimane ancora. Accetterò l'altra risposta anche se mi piacciono entrambi i post ma hai infinitamente più punti :) – Schultz9999