Contractul de design este o idee împrumutată din limbajul de programare Eiffel. .NET 4 System.Diagnostics.Contracts namespace include clase pentru verificări de cod static și verificări în timp real care pot fi utilizate de toate limbile .NET.
Prin această funcționalitate pot fi definite precondițiile, postcondițiile și invarianții în cadrul metodei. Precondițiile enumeră cerințele pe care trebuie să le îndeplinească parametrii, postcondițiile definesc cerințele pentru datele returnate și invarianții - cerințele pentru variabilele din cadrul metodei în sine.
Informații despre contract pot fi compilate în cod de depanare și de lucru. De asemenea, puteți defini un ansamblu de contract separat, iar multe verificări pot fi efectuate și în mod static, fără a rula aplicația.
Contractele pot fi definite pe interfețe; acest lucru va impune implementarea interfețelor pentru a îndeplini cerințele acestor contracte. Instrumentele contractuale pot rescrie ansamblul prin introducerea verificărilor contractuale în cod pentru a le executa în timpul funcționării aplicației, verificarea contractelor la momentul compilării și adăugarea informațiilor contractuale către documentația XML generată.
Contractele cod sunt definite de clasa Contract. Toate cerințele contractelor, care sunt stabilite în metodă, indiferent dacă acestea sunt condiții preliminare sau postcondiții, trebuie plasate la începutul metodei. De asemenea, puteți asocia un procesor global de evenimente evenimentului ContractFailed, care va fi solicitat pentru fiecare încălcare a contractului în timpul execuției. Apelarea SetHandled () cu parametrul e de tip ContractFailedEventArgs va opri comportamentul standard dacă excepția este ridicată.
Precondiții (Necesită)
Condițiile prealabile verifică parametrii parcurși metodei Necesită () și Necesită
Contractul prezentat mai jos aruncă o ArgumentNullException dacă argumentul o este nul. Nu se generează o excepție dacă managerul de evenimente ContractFailed stabilește evenimentul pentru a fi tratat. În plus, dacă caseta de selectare Assert on Failure contract este verificată în fereastra proprietăților proiectului, în loc de a genera o excepție specifică, metoda Trace.Assert () este chemată pentru a termina programul:
Apeluri Necesare
Într-o masă imensă de cod moștenire, argumentele sunt deseori verificate de instrucțiunile if, cu excepția aruncată în cazul în care condiția specificată este încălcată. Din cauza contractelor cod, nu este nevoie să rescrieți verificarea. Doar adăugați o linie de cod:
EndContractBlock () specifică faptul că codul anterior ar trebui procesat ca un contract. În cazul în care sunt utilizați alți operatori de contracte, nu este necesar ca EndContractBlock ().
Pentru a testa colecțiile folosite ca argumente, clasa Contract oferă metodele Exists () și ForAll (). Metoda ForAll () verifică fiecare articol din colecție pentru conformare. Următorul exemplu verifică dacă fiecare element din colecție are o valoare mai mică de 12. Folosind metoda Exists (), puteți verifica dacă condiția se potrivește cu cel puțin un element de colectare:
Ambele metode, Exists () și ForAll (), au o supraîncărcare, care în loc de IEnumerable
Posturi (asigură)
Definiția postcondițiilor asigură respectarea anumitor condiții privind datele partajate și valorile returnate. Și deși definesc anumite garanții cu privire la valorile returnate, totuși, ele trebuie să fie scrise la începutul metodei; toate cerințele contractuale trebuie stabilite la începutul metodei.
Asigură () și EnsuresOnThrow
Cu EnsuresOnThrow
Pentru a garanta valoarea returnată cu contractul Ensures (), se poate folosi o valoare specială Result
De asemenea, puteți compara valoarea cu valoarea veche. Aceasta se face folosind metoda 01dValue
invarianți
Invarianții definesc contracte pentru variabile pe durata de viață a metodei. Contract.Requires () specifică cerințele de intrare, Contract.Ensures () - cerințe pentru sfârșitul metodei. Contract.Invariant () definește condițiile care trebuie îndeplinite pentru durata de viață a metodei: