Ce face struct
Un struct este un tip valoare, la fel ca int sau DateTime: variabila conține direct datele, nu o referință. La atribuire și la transmiterea într-o metodă se face o copie, așa că modificarea copiei nu atinge originalul. O variabilă struct nu poate fi null (decât ca Punct?).
Struct-urile sunt potrivite pentru valori mici (puncte, intervale, sume cu monedă) care nu se modifică după creare. Marchează-le readonly struct ca să garantezi imutabilitatea. Pentru egalitate după valori și ToString generat automat există record struct.
Nu pot moșteni și nu pot fi moștenite, dar pot implementa interfețe. Struct-urile mari (peste câteva zeci de octeți) se copiază scump; acolo o clasă este de obicei mai bună.
Exemple
Exemplul 1: Copiere la atribuire: struct față de clasă
var p1 = new PunctStruct { X = 1 };
var p2 = p1;
p2.X = 99;
Console.WriteLine($"struct: {p1.X} {p2.X}");
var c1 = new PunctClasa { X = 1 };
var c2 = c1;
c2.X = 99;
Console.WriteLine($"class: {c1.X} {c2.X}");
struct PunctStruct { public int X; }
class PunctClasa { public int X; }
Rezultat
struct: 1 99
class: 99 99
Exemplul 2: readonly record struct pentru o sumă de bani
record struct generează egalitatea după valori și ToString; with creează o copie modificată.
var pret = new Suma(120, "RON");
var cuReducere = pret with { Valoare = 100 };
Console.WriteLine(pret);
Console.WriteLine(cuReducere);
Console.WriteLine(pret == new Suma(120, "RON"));
readonly record struct Suma(int Valoare, string Moneda);
Rezultat
Suma { Valoare = 120, Moneda = RON }
Suma { Valoare = 100, Moneda = RON }
True
Greșeli frecvente
- Modificarea unui struct dintr-o listă:
lista[0].X = 5nu se compilează (CS1612), pentru că indexarea întoarce o copie. Înlocuiește elementul întreg. - Struct-urile mutabile duc la erori greu de găsit: modifici o copie și crezi că ai modificat originalul. Fă-le
readonly. - Folosirea unui struct ca
objectsau interfață îl împachetează (boxing) pe heap, ceea ce anulează avantajul de performanță.
Comenzi înrudite
ref, out și in: Transmit un argument prin referință: ref îl poate citi și modifica, out trebuie setat de metodă, in este doar pentru citire.