Dictionary în C# (.NET)

Colecții generice .NET 2.0+

Stochează perechi cheie-valoare într-o tabelă de dispersie (hash table) cu căutare, inserare și ștergere în timp constant O(1).

Sintaxă C#
var dict = new Dictionary<string, int>(); dict["cheie"] = 10; if (dict.TryGetValue("cheie", out int v)) { ... }

Ce face Dictionary<TKey, TValue>

Clasa System.Collections.Generic.Dictionary<TKey, TValue> implementează o tabelă de dispersie (hash table) care asociază chei unice (TKey) cu valori (TValue). Căutarea unei chei prin TryGetValue sau ContainsKey are o complexitate medie de O(1) (timp constant, indiferent dacă dicționarul are 10 sau 1.000.000 de intrări), spre deosebire de căutarea liniară O(n) într-un List<T>.

Există o diferență importantă între metoda dict.Add(cheie, valoare) și indexatorul dict[cheie] = valoare: dacă cheia există deja în dicționar, Add aruncă ArgumentException, în timp ce indexatorul dict[cheie] = valoare suprascrie valoarea existentă (sau o adaugă dacă nu există). Pentru citire sigură, metoda dict.TryGetValue(cheie, out var valoare) este standardul de aur în C#, deoarece face o singură căutare de hash și nu aruncă excepții când cheia lipsește.

Parametri, metode și opțiuni

Parametru / Metodă Descriere
dict[key] = value Adaugă perechea în dicționar dacă cheia nu există sau actualizează valoarea dacă cheia există deja.
dict.Add(TKey key, TValue val) / TryAdd Adaugă o cheie nouă; Add aruncă excepție la duplicate, în timp ce TryAdd returnează false fără a modifica dicționarul.
dict.TryGetValue(TKey key, out TValue val) Returnează true și populează parametrul out val dacă cheia există; altfel returnează false (o singură căutare în hash).
dict.ContainsKey(TKey key) Verifică în timp O(1) dacă o cheie este prezentă în dicționar.
dict.Remove(TKey key, out TValue val) Elimină cheia din dicționar și extrage simultan valoarea asociată dacă a existat.
new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase) Construiește un dicționar cu chei de tip string insensibile la majuscule/minuscule.

Exemple

Exemplul 1: Citire sigură cu TryGetValue și deconstrucție în foreach

Folosim StringComparer.OrdinalIgnoreCase pentru ca dicționarul să trateze codurile de țară "ro" și "RO" ca fiind aceeași cheie.

var coteTva = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
{
    ["RO"] = 19,
    ["DE"] = 19,
    ["HU"] = 27
};

coteTva["FR"] = 20; // adăugare prin indexator
coteTva.TryAdd("RO", 21); // ignorat, deoarece cheia "RO" există deja

if (coteTva.TryGetValue("ro", out int cotaRo))
{
    Console.WriteLine($"Cota TVA pentru România: {cotaRo}%");
}

foreach (var (tara, cota) in coteTva)
{
    Console.WriteLine($"{tara}: {cota}%");
}

Ieșire în consolă

Cota TVA pentru România: 19%
RO: 19%
DE: 19%
HU: 27%
FR: 20%

Exemplul 2: Numărarea frecvenței cuvintelor cu GetValueOrDefault

Metoda de extensie GetValueOrDefault(cheie, 0) simplifică contorizarea elementelor într-o singură linie în interiorul buclei.

string[] loguri = ["INFO", "WARN", "INFO", "ERROR", "INFO", "WARN"];
var frecventa = new Dictionary<string, int>();

foreach (string nivel in loguri)
{
    frecventa[nivel] = frecventa.GetValueOrDefault(nivel, 0) + 1;
}

foreach (var (nivel, nr) in frecventa)
{
    Console.WriteLine($"{nivel}: {nr} apariții");
}

Ieșire în consolă

INFO: 3 apariții
WARN: 2 apariții
ERROR: 1 apariții

Greșeli frecvente

  • Citirea directă prin indexator var val = dict["cheieInexistenta"]; fără a ști sigur că cheia există — spre deosebire de JavaScript sau PHP (care returnează undefined / null), în C# indexatorul aruncă KeyNotFoundException. Folosește TryGetValue sau GetValueOrDefault.
  • Verificarea dublă if (dict.ContainsKey(k)) { var v = dict[k]; } — această secvență calculează hash-ul și caută cheia de două ori; înlocuiește-o cu if (dict.TryGetValue(k, out var v)) { ... }.

Funcții și concepte înrudite

  • List<T>: Stochează o listă generică redimensionabilă dinamic, cu acces rapid după index și metode de adăugare, ștergere și căutare.
  • HashSet<T>: Menține o mulțime neordonată de elemente unice cu verificare de apartenență în timp O(1) și operații matematice pe mulțimi.
  • GroupBy: Grupează elementele unei secvențe după o cheie comună pentru a calcula statistici, sume și agregări pe categorii.