Ce face Class, Properties { get; init; } și Primary Constructors
În C#, clasele (class) încapsulează starea și comportamentul prin proprietăți (Properties) în locul câmpurilor publice și al metodelor manuale getX() / setX(). O proprietate auto-implementată precum public decimal Sold { get; private set; } generează automat în fundal un câmp privat și permite citirea publică, dar restricționează modificarea doar în interiorul clasei.
Versiunile recente de C# au eliminat aproape complet codul repetitiv (boilerplate): accesorul init (C# 9) permite setarea unei proprietăți doar la crearea obiectului (în constructor sau în object initializer new Cont { Iban = "..." }), după care proprietatea devine imutabilă; modificatorul required (C# 11) îl obligă pe apelant să furnizeze o valoare pentru acea proprietate la inițializare; iar Primary Constructors pentru clase (C# 12) permit declararea parametrilor de constructor (de exemplu dependențele pentru Dependency Injection) direct în antetul clasei.
Parametri, metode și opțiuni
| Parametru / Metodă | Descriere |
|---|---|
{ get; set; } |
Proprietate auto-implementată citibilă și modificabilă oricând după crearea obiectului. |
{ get; private set; } |
Proprietate citibilă din exterior, dar modificabilă exclusiv prin metodele interne ale clasei. |
{ get; init; } |
Proprietate care poate fi setată doar în timpul construcției / inițializării obiectului (C# 9+), devenind apoi read-only. |
required public T Prop { get; init; } |
Forțează la compilare inițializarea proprietății în blocul new Clasa { Prop = ... } (C# 11+). |
public class Nume(Tip param) |
Constructor primar (C# 12+): parametrul param este disponibil în toate metodele și proprietățile clasei. |
public Tip Prop => expresie; |
Proprietate calculată (expression-bodied property, doar cu get) evaluată la fiecare citire. |
Exemple
Exemplul 1: Clasă cu required, { get; init; } și încapsulare cu { get; private set; }
Proprietățile de identitate (Iban, Titular) sunt marcate cu required și init (nu mai pot fi schimbate ulterior), iar Sold poate fi modificat doar prin metodele validate Depune și Retrage.
var cont = new ContBancar
{
Iban = "RO49AAAA1B31007593840000",
Titular = "Andrei Ionescu"
};
cont.Depune(1500m);
cont.Retrage(350m);
Console.WriteLine($"{cont.Titular} ({cont.Iban}) -> Sold: {cont.Sold:F2} RON (Activ: {cont.EsteActiv})");
public class ContBancar
{
public required string Iban { get; init; }
public required string Titular { get; init; }
public decimal Sold { get; private set; }
public bool EsteActiv => Sold > 0m;
public void Depune(decimal suma)
{
if (suma <= 0) throw new ArgumentOutOfRangeException(nameof(suma));
Sold += suma;
}
public void Retrage(decimal suma)
{
if (suma <= 0 || suma > Sold) throw new InvalidOperationException("Fonduri insuficiente.");
Sold -= suma;
}
}
Ieșire în consolă
Andrei Ionescu (RO49AAAA1B31007593840000) -> Sold: 1150.00 RON (Activ: True)
Exemplul 2: Constructor primar (Primary Constructor) în C# 12 pentru servicii
În C# 12, nu mai este nevoie să declari un câmp privat private readonly decimal _cotaTva; și un constructor separat: parametrii din antetul clasei sunt capturați automat.
var calculator = new CalculatorPret(cotaTva: 0.19m, moneda: "RON");
Console.WriteLine(calculator.FormateazaPretCuTva(100m));
Console.WriteLine(calculator.FormateazaPretCuTva(250m));
public class CalculatorPret(decimal cotaTva, string moneda)
{
public decimal CalculeazaBrut(decimal pretNet) => Math.Round(pretNet * (1 + cotaTva), 2);
public string FormateazaPretCuTva(decimal pretNet) =>
$"Net: {pretNet:F2} {moneda} -> Cu TVA ({cotaTva:P0}): {CalculeazaBrut(pretNet):F2} {moneda}";
}
Ieșire în consolă
Net: 100.00 RON -> Cu TVA (19%): 119.00 RON
Net: 250.00 RON -> Cu TVA (19%): 297.50 RON
Greșeli frecvente
- Expunerea unor câmpuri publice (
public string Nume;) în loc de proprietăți (public string Nume { get; set; }) — bibliotecile de serializare, validare și ORM-urile (precum Entity Framework Core sau ASP.NET Core Model Binding) se bazează pe proprietăți. - Lăsarea tuturor proprietăților cu
{ get; set; }public atunci când obiectul nu ar trebui modificat după creare; preferă{ get; init; }sau{ get; private set; }pentru a preveni mutațiile accidentale.
Funcții și concepte înrudite
record și imutabilitate: Definește într-o singură linie modele de date imutabile cu egalitate bazată pe valoare, afișare automată și clonare nedistructivă (with).interface și tipuri generice <T>: Definește contracte decuplate prin interfețe și scrie clase sau metode reutilizabile și sigure la compilare prin parametri generici <T>.JsonSerializer (System.Text.Json): Serializează obiecte C# în format JSON și deserializează text JSON înapoi în tipuri puternic tipizate, cu performanță nativă ridicată.