struct în C# (.NET)

OOP modern și programare asincronă C# 1.0 (readonly struct: C# 7.2, record struct: C# 10)

Tip valoare: se copiază la atribuire și la transmitere, nu are null și e potrivit pentru date mici și imutabile.

Sintaxă C#
readonly struct Punct(int x, int y) { public int X { get; } = x; public int Y { get; } = y; }

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 = 5 nu 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 object sau 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.