CodeGym /Cours /C# SELF /Dictionnaire : Dictionary...

Dictionnaire : Dictionary<TKey, TValue>

C# SELF
Niveau 27 , Leçon 3
Disponible

1. Introduction

Imagine que t’es le proprio d’une petite boutique, et t’as une liste de produits. Chaque produit a son code unique (genre ART-001, ART-002) et bien sûr, un nom, un prix, une quantité en stock.

Si tu stockais tout ça dans une List<T>, où T — c’est, par exemple, notre future classe Product, alors pour trouver le produit avec le code ART-005, tu devrais parcourir toute la liste :
"C’est ART-001 ? Non. C’est ART-002 ? Non... Et là, ART-005 ! Trouvé !"
S’il y a 10 produits, c’est pas grave. Mais si t’en as 10 000 ? Ou 100 000 ? La recherche de chaque produit va prendre un temps fou. Ton client va devoir attendre trop longtemps pour que tu retrouves son paquet de biscuits préféré. Pas cool !

On a besoin d’un moyen pour accéder direct au bon produit si on connaît son code unique, sans tout parcourir. Donc, il nous faut une sorte de "clé" qui pointe direct sur la "valeur" qu’on veut.

Découverte de Dictionary

Et voilà que débarque Dictionary<TKey, TValue> ! Imagine que c’est pas juste une liste, mais un annuaire super intelligent. Dans un annuaire classique, tu cherches un numéro de téléphone (valeur) par le nom de la personne (clé). Tu ouvres à la lettre "A", tu cherches "Alexis", et hop, t’as son numéro. Pas besoin de tout feuilleter.

Pareil avec Dictionary (ou "Dictionnaire" en français) : il stocke les données sous forme de paires "clé-valeur".

  • Clé (TKey) : C’est l’identifiant unique de chaque élément. Comme un nom dans l’annuaire ou le code d’un produit. C’est avec cette clé que tu vas chercher la valeur. La clé doit être unique dans le dico. Si tu essaies d’ajouter un élément avec une clé déjà existante, Dictionary va râler.
  • Valeur (TValue) : C’est les données que tu veux stocker. Ça peut être un numéro de téléphone, le prix d’un produit, la définition d’un terme — ce que tu veux !

Les lettres TKey et TValue entre chevrons <TKey, TValue> veulent dire que Dictionary est une collection générique (Generic). C’est toi qui choisis le type de la clé et de la valeur. Ça peut être string pour la clé (nom, code), int (ID utilisateur), ou même ta propre classe. Et la valeur peut être int, string, double ou carrément un objet.

L’avantage ? Accès instantané ! Grâce à sa structure interne spéciale (une table de hachage, pour les curieux, mais t’inquiète, pas besoin de savoir comment ça marche pour l’instant), Dictionary te permet de trouver une valeur par sa clé en un temps super court, peu importe s’il y a dix ou un million d’éléments. C’est comme un super-index dans une énorme bibliothèque : tu dis "je veux le livre sur C#", et on te montre direct où il est, sans te faire fouiller toutes les étagères.

Allez, on passe à la pratique ! On va faire évoluer notre projet en créant un "Mini-dico des termes C#" interactif, histoire de retenir les nouveaux concepts.

2. Bases de la syntaxe : créer un dictionnaire

Comme d’hab : on déclare une variable, mais cette fois on précise deux types — le type de la clé (TKey) et celui de la valeur (TValue) :

// Dico simple : clé - string (login), valeur - string (email)
Dictionary<string, string> userEmails = new Dictionary<string, string>();

// Ou plus court avec var
var userEmails = new Dictionary<string, string>();

Pourquoi il faut préciser les deux types ?
Parce que C# est un langage à typage fort, et le dico doit savoir quels types de clés et de valeurs tu lui donnes.

Ajouter des éléments

Pour ajouter une nouvelle paire "clé-valeur", on utilise la méthode Add. La clé doit être unique !

userEmails.Add("john", "john@example.com");
userEmails.Add("pete", "pete@gmail.com");

Si tu essaies d’ajouter encore une fois avec la même clé — le dico va râler et balancer une exception.

Accéder aux valeurs par la clé

Le plus cool avec un dico — c’est de choper la valeur par la clé :

string email = userEmails["john"];
Console.WriteLine(email); // john@example.com

Si tu demandes une clé qui existe pas, le programme va gueuler (exception KeyNotFoundException). Pour bosser tranquille, on va bientôt voir comment vérifier si la clé existe.

Modifier la valeur d’une clé

Si la clé existe déjà, tu fais juste une nouvelle affectation :

userEmails["john"] = "john@newmail.ru"; // maintenant l’email de Vasya a changé

Si la clé n’existait pas — ça crée un nouvel élément dans le dico.

Exemple avec des utilisateurs

On va améliorer notre appli d’apprentissage. Avant, on stockait la liste des tâches (List<string> tasks;) pour une appli ToDo. Maintenant, on veut ajouter une "authentification" : chaque utilisateur a besoin d’un email.

Voilà à quoi ça peut ressembler :

// UserId — c’est un string, Email aussi
var users = new Dictionary<string, string>();
users.Add("admin", "admin@myapp.com");
users.Add("alice", "alice@wonderland.com");
users.Add("bob", "bob@builder.com");

Maintenant tu peux toujours retrouver l’email d’un utilisateur par son login :

Console.WriteLine(users["alice"]); // => alice@wonderland.com

3. Méthodes et propriétés principales de Dictionary

Méthode/Propriété Description
Add(key, value)
Ajoute une nouvelle paire "clé-valeur".
Remove(key)
Supprime un élément par sa clé.
ContainsKey(key)
Vérifie si la clé existe.
ContainsValue(value)
Vérifie si la valeur existe (lent !).
TryGetValue(key, out val)
Récupère la valeur par la clé sans balancer d’exception.
Count
Nombre de paires "clé-valeur" dans le dico.
Keys
Collection de toutes les clés.
Values
Collection de toutes les valeurs.

Vérifier si une clé existe

Le plus courant (et le plus safe) — c’est de vérifier d’abord si la clé existe :

if (users.ContainsKey("diana"))
{
    Console.WriteLine(users["diana"]);
}
else
{
    Console.WriteLine("Utilisateur diana non trouvé !");
}

La méthode safe : TryGetValue

La méthode TryGetValue permet d’éviter les exceptions :

if (users.TryGetValue("bob", out string email))
{
    Console.WriteLine($"Mail de Bob : {email}");
}
else
{
    Console.WriteLine("Bob non trouvé !");
}

C’est une bonne pratique et on te la demandera sûrement en entretien — retiens-la direct ! En plus, cette méthode est plus rapide que le combo ContainsKey + accès par index.

4. Parcourir un dictionnaire : boucle foreach

Si tu veux passer sur toutes les paires, utilise la boucle foreach. Chaque élément du dico est un objet de type KeyValuePair<TKey, TValue> :

foreach (var pair in users)
{
    Console.WriteLine($"Login : {pair.Key}, Email : {pair.Value}");
}

Ou, si tu veux faire le malin :

foreach (var (login, email) in users)
{
    Console.WriteLine($"{login}: {email}");
}
// Ce genre de syntaxe est dispo grâce à la déconstruction de tuples (C# 7+).

5. Supprimer et modifier des valeurs

Supprimer un utilisateur par son login, c’est simple :

users.Remove("alice");

Si la clé existe pas — ça renvoie false. Tu peux tenter de supprimer sans crainte d’exception.

Modifier l’email d’un utilisateur :

users["bob"] = "bob@constructor.com";

Si la clé existait pas — ça crée une nouvelle paire !

6. Propriétés utiles Keys et Values

Si tu veux juste la liste des logins (clés) ou juste les emails (valeurs), utilise les collections Keys et Values :

foreach (string login in users.Keys)
{
    Console.WriteLine("Login : " + login);
}

foreach (string email in users.Values)
{
    Console.WriteLine("Email : " + email);
}

7. Points importants sur les dictionnaires

Les clés doivent être uniques

Impossible d’ajouter deux fois la même clé. Si tu tentes — exception directe. Cette unicité protège tes données : un utilisateur ne peut pas avoir deux emails (pour une seule entrée).

La clé ne peut pas être null (pour string)

Pour les clés de type string, essayer d’ajouter une clé null va causer une erreur (ArgumentNullException). Si jamais t’as pas de clé, réfléchis — c’est sûrement un souci dans ta logique de données.

Pourquoi la recherche dans un dico est-elle si rapide ?

Dictionary fonctionne "sous le capot" avec une table de hachage. Ça veut dire que la recherche par clé, c’est pas un parcours de tous les éléments, mais un calcul éclair d’une "fonction de hachage" et un accès quasi direct à la case où est stockée la valeur.

Qu’est-ce qu’on peut utiliser comme clé ?

  • N’importe quel type pour lequel l’égalité et le hash sont bien définis (méthodes Equals et GetHashCode()).
  • En général, c’est string, int, Guid ou tes propres types (mais là, fais gaffe à bien redéfinir Equals/GetHashCode, sinon tu risques des bugs marrants).

8. On ajoute un dico à l’appli

Dans notre mini-appli ToDo, on va ajouter un dico d’utilisateurs, et coder une fonction pour chercher l’email par login avec gestion des erreurs :

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // Dico des utilisateurs : login => email
        var users = new Dictionary<string, string>
        {
            { "admin", "admin@myapp.com" },
            { "alice", "alice@wonderland.com" },
            { "bob", "bob@builder.com" }
        };

        Console.WriteLine("Tape le login de l’utilisateur pour chercher son email :");
        string login = Console.ReadLine();

        // Recherche safe de l’email
        if (users.TryGetValue(login, out string email))
        {
            Console.WriteLine($"Email de l’utilisateur {login} : {email}");
        }
        else
        {
            Console.WriteLine($"Utilisateur {login} non trouvé.");
        }

        // Parcours de tous les utilisateurs
        Console.WriteLine("\nListe de tous les utilisateurs :");
        foreach (var pair in users)
        {
            Console.WriteLine($"{pair.Key} => {pair.Value}");
        }
    }
}

9. Erreurs typiques et pièges de débutant

Parfois, on a trop envie de faire comme ça :

// En espérant que si la clé existe pas — tout ira bien
string value = users["nonexistent"]; // Bam ! KeyNotFoundException !

N’oublie pas : vérifie toujours si la clé existe (ContainsKey ou TryGetValue) si t’es pas sûr qu’elle est là.

Aussi, rappelle-toi : parcourir les valeurs ne garantit pas qu’elles sont uniques ! Le même email peut être associé à deux logins (si t’as perdu le contrôle sur l’unicité des valeurs, pas des clés).

On se trompe aussi sur les méthodes — genre, on essaie de supprimer par la valeur :

users.Remove("bob@builder.com"); // Ça ne supprime rien ! Il attend une clé, pas une valeur.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION