C# dictionary
Création & initialisation
Basique
var d = new Dictionary<string, int>();
d["alice"] = 25; // ajoute (ou met à jour)
d.Add("bob", 30); // ajoute (exception si la clé existe)
Capacité initiale
var d = new Dictionary<string, int>(capacity: 1_000);
Comparateur (OrdinalIgnoreCase)
var d = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
d["Paris"] = 75;
Console.WriteLine(d.ContainsKey("paris")); // True
Initialisation par collection
var d = new Dictionary<int, string>
{
[1] = "un",
[2] = "deux"
};
Depuis une séquence (LINQ ToDictionary)
var fruits = new[] { "pomme", "banane", "kiwi" };
var d = fruits.ToDictionary(
keySelector: f => f,
elementSelector: f => f.Length);
Ajouter / Mettre à jour
Ajout, TryAdd, indexeur
var d = new Dictionary<string, int>();
d.Add("alice", 25);
bool added = d.TryAdd("alice", 26); // false si déjà présent
d["alice"] = 27; // upsert
Pattern Upsert (TryGetValue)
if (d.TryGetValue("bob", out int age))
d["bob"] = age + 1;
else
d["bob"] = 30;
Rechercher / Lire
TryGetValue & GetValueOrDefault
if (d.TryGetValue("alice", out int age))
{
Console.WriteLine(age);
}
int valueOrDefault = d.GetValueOrDefault("charlie", -1);
// Attention: d["clé"] lève KeyNotFoundException si la clé est absente.
Itération
Parcourir KeyValuePair
foreach (var kv in d)
{
Console.WriteLine($"{kv.Key} => {kv.Value}");
}
Déconstruction (C# 7+)
foreach (var (key, val) in d)
{
Console.WriteLine($"{key} => {val}");
}
Itérer clés et valeurs séparément
foreach (var k in d.Keys) { /* ... */ }
foreach (var v in d.Values) { /* ... */ }
Suppression / Nettoyage
Remove, Remove(out), Clear
d.Remove("alice");
bool removed = d.Remove("bob", out int oldValue);
d.Clear();
Capacité
EnsureCapacity & TrimExcess
var d = new Dictionary<string, int>(capacity: 10_000);
d.EnsureCapacity(50_000);
d.TrimExcess();
Comparateurs de clé
Ignorer la casse (strings)
var d = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
Comparateur personnalisé (IEqualityComparer)
class Point2D
{
public int X { get; init; }
public int Y { get; init; }
}
class PointComparer : IEqualityComparer<Point2D>
{
public bool Equals(Point2D? a, Point2D? b)
=> a is not null && b is not null && a.X == b.X && a.Y == b.Y;
public int GetHashCode(Point2D p) => HashCode.Combine(p.X, p.Y);
}
var d = new Dictionary<Point2D, string>(new PointComparer());
d[new Point2D { X = 1, Y = 2 }] = "A";
Scénarios utiles
Dictionnaire de listes (accumulateur)
var map = new Dictionary<string, List<int>>();
void Add(string key, int value)
{
if (!map.TryGetValue(key, out var list))
map[key] = list = new List<int>();
list.Add(value);
}
Add("alice", 1);
Add("alice", 2);
Add("bob", 9);
Dictionnaires imbriqués
var grid = new Dictionary<int, Dictionary<int, double>>();
void Set(int x, int y, double v)
{
if (!grid.TryGetValue(x, out var inner))
grid[x] = inner = new Dictionary<int, double>();
inner[y] = v;
}
Regroupement avec LINQ (ToLookup / ToDictionary)
var people = new[]
{
new { City = "Paris", Name = "Alice" },
new { City = "Paris", Name = "Bob" },
new { City = "Lyon", Name = "Claire"}
};
var byCity = people.ToLookup(p => p.City, p => p.Name);
var dict = people
.GroupBy(p => p.City, p => p.Name)
.ToDictionary(g => g.Key, g => g.ToList());
Vue en lecture seule
IReadOnlyDictionary<string, int> ro = d; // interface read-only
Alternatives
SortedDictionary (ordre trié, O(log n))
var sd = new SortedDictionary<string, int>(StringComparer.Ordinal);
ConcurrentDictionary (thread-safe)
var cd = new ConcurrentDictionary<string, int>(StringComparer.Ordinal);
int val = cd.GetOrAdd("alice", _ => 1);
int newVal = cd.AddOrUpdate(
"alice",
addValueFactory: _ => 1,
updateValueFactory: (_, old) => old + 1);
Sérialisation JSON
System.Text.Json
var d = new Dictionary<string, int>
{
["a"] = 1,
["b"] = 2
};
string json = JsonSerializer.Serialize(d);
var d2 = JsonSerializer.Deserialize<Dictionary<string,int>>(json)!;
Recettes courantes
Incrémenter un compteur par clé
void Inc(Dictionary<string,int> counts, string key, int delta = 1)
{
counts.TryGetValue(key, out int current);
counts[key] = current + delta;
}
Fusionner deux dictionnaires (somme des valeurs)
var a = new Dictionary<string,int> { ["x"] = 1, ["y"] = 2 };
var b = new Dictionary<string,int> { ["y"] = 3, ["z"] = 4 };
foreach (var (k, v) in b)
{
a[k] = a.TryGetValue(k, out int old) ? old + v : v;
}
// a = { x:1, y:5, z:4 }
Copier si absent (pattern TryAddOrGetExisting)
TValue GetOrAdd<TKey,TValue>(
Dictionary<TKey,TValue> d, TKey key, Func<TValue> factory)
where TKey : notnull
{
if (!d.TryGetValue(key, out var val))
d[key] = val = factory();
return val;
}
Tri pour l'affichage
Itération triée via LINQ
var sorted = d.OrderBy(kv => kv.Key, StringComparer.Ordinal);
foreach (var (k, v) in sorted)
Console.WriteLine($"{k}={v}");