Tipul Record & Imutabilitate în C# în C# (.NET)

Crearea de tipuri de date imutabile cu egalitate bazată pe valori (value-based equality) și mutare non-distructivă prin expresia 'with'.

Sintaxă C#
public record Nume(string Nume, int Varsta); & with { ... }

În programarea orientată pe obiecte clasică, două instanțe diferite ale aceleiași clase cu date identice (`new User(„Ion”)` și `new User(„Ion”)`) nu sunt considerate egale cu operatorul `==` deoarece referențiază adrese diferite de memorie. Implementarea egalității pe valori necesita suprascrierea metodelor `Equals`, `GetHashCode` și a operatorilor de egalitate.

Tipul record (și `record struct`) automatizează complet acest comportament: compilatorul generează automat egalitatea pe baza valorilor tuturor proprietăților, formatarea curată pentru afișare `ToString()`, și protecția la mutare prin proprietăți init.

Pentru modificarea sigură a datelor, C# pune la dispoziție operatorul with (Non-destructive mutation): creează o copie nouă a obiectului cu doar anumite proprietăți modificate, păstrând obiectul original 100% intact, principiu vital în arhitecturi de microservicii și procesare concurentă.

Sintaxă, opțiuni și concepte cheie

Opțiune / Concept Descriere practică
public record Nume(...) Declarația pozițională compactă a unui record imutabil.
Value-based Equality Două record-uri sunt egale dacă toate proprietățile lor au aceleași valori.
with { Proprietate = valoare } Clona non-distructivă ce returnează o copie nouă cu atribute modificate.
record struct Varianta alocată pe stivă (Stack) pentru scenarii cu cerințe extreme de performanță fără alocări pe Heap.

Exemple practice și cod

Exemplul 1: Egalitatea pe valori și mutarea non-distructivă cu expresia with

Demonstrarea comportamentului nativ al tipului record.

public record Utilizator(int Id, string Nume, string Rol);

var u1 = new Utilizator(1, "Andrei", "Editor");
var u2 = new Utilizator(1, "Andrei", "Editor");

// 1. Egalitate pe valori automată:
Console.WriteLine(u1 == u2); // Returnează: True !

// 2. Modificare non-distructivă (promovare în Admin fără a modifica u1):
var uAdmin = u1 with { Rol = "Administrator" };

Console.WriteLine(u1);      // Utilizator { Id = 1, Nume = Andrei, Rol = Editor }
Console.WriteLine(uAdmin);  // Utilizator { Id = 1, Nume = Andrei, Rol = Administrator }

Rezultat & Impact

Imutabilitate garantată la nivel de compilator cu sintaxă extrem de elegantă.

Greșeli frecvente și bune practici

  • Utilizarea record-urilor clasice (care sunt tipuri de referință alocate pe Heap) în bucle critice de milioane de iterații în loc de `readonly record struct`.
  • Modificarea colecțiilor interne ale unui record: un record garantează imutabilitatea referințelor, dar dacă conține o `List` obișnuită, elementele din listă pot fi modificate dacă nu folosiți `ImmutableArray`.

Ghiduri și noțiuni înrudite