Saturday, April 20, 2019 04:32

Constante

La fel ca și constantele din matematică, C# definește câmpuri speciale de clase numite constante. Așa cum indică și denumirea lor, odată declarate și inițializate, constantele își mențin valorile, interzicând modificarea lor ulterioară.

Există două tipuri de constante:

  • Constantele pentru care valoarea este stabilită în timpul compilării (constante de timp de compilare)
  • Constantele care au valoarea lor setată în timpul execuției (constante de timp de execuție)

Constantele de timp de compilare sunt declarate folosind modificatorul C# const:

Un secret pe care nu mulți programatori C# îl știu este acela că de fapt constantele de timp de compilare sunt câmpuri statice, chiar dacă acestea nu conțin cuvântul cheie static, și compilatorul interzice utilizarea sa în declarație.

De exemplu, cea mai cunoscută și mai simplă constantă pe care o putem declara este numărul Pi din matematică (sau, mai bine spus, o parte din el):

După cum puteți vedea, am declarat o constantă de tip double prin specificarea unui modificator de acces, urmat de modificatorul const, tipul variabilei și numele său.

O constantă poate fi orice fel de expresie care poate fi evaluată la timpul de compilare. De exemplu:

deoarece, după cum știm din clasele de matematică, Pi poate fi reprezentat și ca împărțirea aproximativă a numerelor 22 și 7. Deci:

va afișa

constante

Deoarece constantele sunt… ei bine, constante, nu le putem modifica/aloca în nici un alt loc sau moment, cu excepția declarației. Acest cod:

va genera următoarea eroare de compilator: Un câmp const necesită o valoare să fie furnizată (A const field requires a value to be provided).

Există un alt pericol pe care unii dintre voi, un pic mai aventurieri, îl pot întâlni. Să luăm un exemplu pentru a ilustra acest lucru.

Să considerăm că dorim să creăm o clasă Culoare utilizând modelul RGB (red green blue – roșu verde albastru), care specifică faptul că orice culoare este o combinație de valori diferite de roșu, verde și albastru, specificate ca întregi în intervalul 0255. De exemplu, negru este reprezentat ca (0, 0, 0), alb ca (255, 255, 255), albastru ca (0, 0, 255), etc.

Deci, creăm obiectul Culoare definind 3 câmpuri private și un constructor pentru inițializarea lor:

Acum, să luăm în considerare faptul că unele culori sunt folosite mai frecvent, de exemplu alb și negru (da, știu că nici una din ele nu este culoare, dar de dragul lecției…). Prin urmare, ar fi foarte util dacă am oferi utilizatorilor anumite constante care să dețină aceste valori ale culorilor, pentru a nu mai fi nevoie să le specificăm de fiecare dată:

Totul vi se pare OK? Ei bine, în mod ciudat, nu este: ‘Culoare.NEGRU’ este de tip ‘Culoare’. Un câmp const al unui tip de referință altul decât string poate fi inițializat numai cu null (‘Color.BLACK’ is of type ‘Color’. A const field of a reference type other than string can only be initialized with null). Motivul pentru această eroare de compilator este faptul că o constantă declarată cu cuvântul const pot fi doar din următoarele tipuri:

  1. Tipuri primitive: sbyte, byte, short, ushort, int, uint, long, ulong, char,  float, double, decimal, bool.
  2. Tipuri enumerate (vom învăța despre enumerări în viitor).
  3. Tipuri de referință (mai ales tipul string).

Problema referitoare la compilarea clasei din exemplul nostru este legată de tipurile de referință și de restricționarea compilatorului de a nu permite utilizarea simultană a operatorului new când se declară o constantă, atunci când această constantă este declarată cu modificatorul const, cu excepția cazului în care tipul de referință poate fi calculată la momentul compilării.

După cum putem ghici, singurul tip de referință care poate fi calculat la momentul compilării atunci când utilizăm operatorul new, este string. Prin urmare, singurele posibilități pentru constantele de tip de referință care sunt declarate cu modificatorul const sunt după cum urmează:

  • Constantele trebuie să fie de tip string.
  • Valoarea pe care o atribuim unei constante de tip de referință, alta decât string, este null.

Deci, am aflat că prin utilizarea modificatorului const nu vom putea declara constantele NEGRU și ALB de tip Culoare în clasa noastră de culori, deoarece nu sunt nule. În următoarea secțiune vă voi arăta cum să rezolvați această problemă.

Constantele de timp de execuție sunt de folos când trebuie să declarăm constante de tip de referință care nu pot fi calculate la momentul compilării. Acestea sunt declarate astfel:

Aceasta presupune că <tip_referinta> este un tip de valoare care nu este cunoscută la momentul compilării. Deci, corectând codului de mai sus:

va face ca programul nostru să fie compilat și să ruleze fără probleme.

S-ar putea să vă întrebați, care este utilizarea reală a unei valori pe care nu o putem schimba? Ei bine, constantele sunt folosite în programare pentru a evita repetarea numerelor, șirurilor sau a altor valori comune (literale) în program și pentru a putea să le schimbăm cu ușurință. Utilizarea constantelor în loc de repetiții barbare de valori întipărite direct în cod facilitează citirea și menținerea codului și este o practică foarte recomandată. Potrivit unor autori, toți literalii, alții decât 0, 1, -1, șir gol, adevărat, fals și nul, trebuie să fie declarați ca și constante, dar eu sunt mai degrabă sceptică în această privință, deoarece acest lucru poate face dificilă citirea și păstrarea codului, în loc să îl simplifice. Prin urmare, se spune că valorile care apar mai mult de o dată în program sau care se pot schimba în timp ar trebui declarate ca fiind constante.

S-ar putea să fi observat că am numit constantele folosind doar majuscule. Poate că ar fi un moment bun să recitiți lecția „Alegerea denumirilor semnificative de variabile„, care explicat acest lucru mai detaliat.

Comments

comments

Tags: , ,

Leave a Reply