Constante, câmpuri și structuri de citire
Constantele claselor
Pe lângă câmpuri, o clasă poate defini constante pentru stocarea datelor. Spre deosebire de câmpuri, valoarea constantelor se stabilește o singură dată, direct la declararea lor, și ulterior nu poate fi modificată. În plus, constantele stochează anumite date care nu se referă la un singur obiect, ci la întreaga clasă. Și pentru a accesa constantele nu se folosește numele obiectului, ci numele clasei:
Person tom = new Person();
tom.name = "Tom";
tom.Print(); // Person: Tom
Console.WriteLine(Person.type); // Person
// Person.type = "User"; // !Eroare: nu se poate modifica o constantă
class Person
{
public const string type = "Person";
public string name = "Undefined";
public void Print() => Console.WriteLine($"{type}: {name}");
}
Aici, în clasa Person, este definită constanta type, care stochează denumirea clasei:
public const string type = "Person";
Numele clasei nu depinde de obiect. Putem crea multe obiecte Person, dar numele clasei nu trebuie să se schimbe - se referă la toate obiectele Person și nu trebuie să se modifice. De aceea, numele tipului poate fi stocat sub formă de constantă.
Trebuie menționat că unei constante trebuie să i se atribuie o valoare imediat la definire.
Similar câmpurilor obișnuite, putem accesa constantele clasei în interiorul acestei clase. De exemplu, în metoda Print, valoarea constantei este afișată pe consolă.
Totuși, dacă dorim să accesăm constanta în afara clasei sale, trebuie să folosim numele clasei:
Console.WriteLine(Person.type); // Person
Astfel, dacă este necesar să stocăm date care se referă la întreaga clasă, putem folosi constante.
Câmpuri de citire și modificatorul readonly
Câmpurile de citire sunt acele câmpuri ale unei clase sau structuri a căror valoare nu poate fi modificată. Acestor câmpuri li se poate atribui o valoare fie direct la declarare, fie în constructor. În alte locuri din program nu se poate atribui valoare acestor câmpuri, se poate doar citi valoarea lor.
Un câmp de citire este declarat cu cuvântul cheie readonly:
Person tom = new Person("Tom");
Console.WriteLine(tom.name);
//tom.name = "Sam"; // !Eroare: nu se poate modifica
class Person
{
public readonly string name = "Undefined"; // poate fi inițializat așa
public Person(string name)
{
this.name = name; // în constructor se poate atribui valoare câmpului de citire
}
public void ChangeName(string otherName)
{
//this.name = otherName; // nu se poate
}
}
Aici, câmpul name stochează numele utilizatorului și este un câmp de citire. I se poate atribui o valoare direct la declarare:
public readonly string name = "Undefined";
Sau i se poate atribui o valoare în constructor:
public Person(string name)
{
this.name = name;
}
În alte locuri din program, inclusiv în clasa Person, nu se poate atribui valoare câmpului de citire.
Compararea constantelor
- Constantele trebuie definite în timpul compilării, în timp ce câmpurile de citire pot fi definite în timpul execuției programului
Valoarea unei constante poate fi stabilită doar la definirea ei.
Un câmp de citire poate fi inițializat fie la definirea lui, fie în constructorul clasei.
- Constantele nu pot folosi modificatorul static, deoarece sunt implicit statice. Câmpurile de citire pot fi fie statice, fie nestatice.
Structuri de citire
Pe lângă câmpurile de citire, în C# putem defini structuri de citire. Pentru aceasta, ele sunt precedate de modificatorul readonly:
readonly struct Person { }
Particularitatea acestor structuri este că toate câmpurile lor trebuie să fie de asemenea câmpuri de citire:
readonly struct Person
{
public readonly string name;
public Person(string name)
{
this.name = name;
}
}
Același lucru se aplică și proprietăților, care trebuie să fie disponibile doar pentru citire:
readonly struct Person
{
public readonly string Name { get; } // nu este necesar să specificăm readonly
public int Age { get; } // proprietate doar pentru citire
public Person(string name, int age)
{
Name = name;
Age = age;
}
}