enum și [Flags] în C# (.NET)

Definește un set fix de constante cu nume (stări, zile, roluri); cu [Flags] valorile se pot combina ca biți.

Sintaxă C#
enum Status { Nou, Trimis, Livrat }   [Flags] enum Drept { Citire = 1, Scriere = 2 }

Ce face enum și [Flags]

Un enum dă nume unor valori întregi: implicit primul membru este 0, următorul 1 și așa mai departe, dar poți da valori explicite. Variabilele de tip enum fac codul ușor de citit (Status.Livrat în loc de 2) și merg natural în switch.

ToString() întoarce numele membrului, Enum.Parse<T> și Enum.TryParse<T> fac conversia inversă, iar Enum.GetValues<T>() (.NET 5) dă toate valorile. Un cast (Status)7 se compilează chiar dacă 7 nu e membru; verifică cu Enum.IsDefined când valoarea vine din afară.

Cu atributul [Flags] și valori putere a lui 2, un singur câmp ține mai multe opțiuni: Drept.Citire | Drept.Scriere. Verificarea se face cu HasFlag sau cu (valoare & Drept.Scriere) != 0.

Exemple

Exemplul 1: Starea unei comenzi

Status s = Status.Trimis;
Console.WriteLine(s);
Console.WriteLine((int)s);

foreach (Status v in Enum.GetValues<Status>())
    Console.Write($"{v} ");
Console.WriteLine();

if (Enum.TryParse("Livrat", out Status citit))
    Console.WriteLine(citit == Status.Livrat);

enum Status { Nou, Trimis, Livrat, Anulat = 10 }

Rezultat

Trimis
1
Nou Trimis Livrat Anulat
True

Exemplul 2: Drepturi combinate cu [Flags]

Drept ana = Drept.Citire | Drept.Scriere;
Console.WriteLine(ana);
Console.WriteLine(ana.HasFlag(Drept.Scriere));
Console.WriteLine(ana.HasFlag(Drept.Stergere));

ana |= Drept.Stergere;
ana &= ~Drept.Scriere;
Console.WriteLine(ana);
Console.WriteLine((int)ana);

[Flags]
enum Drept
{
    Niciunul = 0,
    Citire = 1,
    Scriere = 2,
    Stergere = 4,
}

Rezultat

Citire, Scriere
True
False
Citire, Stergere
5

Greșeli frecvente

  • Valori [Flags] consecutive (1, 2, 3) nu se pot combina corect: 3 este deja 1 | 2. Folosește 1, 2, 4, 8 sau 1 << n.
  • Salvarea în baza de date a valorii numerice și apoi reordonarea membrilor schimbă sensul datelor vechi. Dă valori explicite membrilor care se salvează.
  • Enum.Parse pe text necunoscut aruncă ArgumentException; pentru date de la utilizator folosește TryParse.

Comenzi înrudite

  • struct: Tip valoare: se copiază la atribuire și la transmitere, nu are null și e potrivit pentru date mici și imutabile.
  • int.Parse și int.TryParse: Transformă text în număr: Parse aruncă excepție la text invalid, TryParse returnează false și nu aruncă.