Deux points d'interrogation en C# : pas une erreur, mais un outil puissant
\n\nImaginez : vous écrivez du code en C#, et soudain vous voyez la construction ??. La première pensée — une faute de frappe ? Un signe en trop ? En réalité, c'est l'un des opérateurs les plus élégants et utiles du langage — l'opérateur de coalescence nulle (null-coalescing operator). Si vous avez déjà attrapé une NullReferenceException et maudit tout ce qui existe — cet opérateur deviendra votre bouée de sauvetage.
Dans cet article, nous allons voir ce que signifient deux points d'interrogation en C#, comment les utiliser correctement, en quoi ils diffèrent de l'opérateur ternaire, et montrer des exemples concrets de la pratique. C'est parti !
\n\nQu'est-ce que l'opérateur ?? en C# ?
\n\nL'opérateur ?? (deux points d'interrogation) est un opérateur binaire qui retourne l'opérande de gauche s'il n'est pas égal à null ; sinon, il retourne l'opérande de droite. En termes simples : « Si la gauche n'est pas null — prends la gauche, sinon prends la droite ».
La syntaxe est extrêmement simple :
\n\nvar result = left ?? right;\n\nOù :
\n- \n
left— la valeur qui peut être null ; \n right— la valeur par défaut (ne peut pas être null si le type à droite est nullable). \n
Premier exemple : se sauver de null
\n\nSupposons que vous ayez une variable string? name (chaîne nullable). Vous voulez afficher le nom de l'utilisateur, et s'il n'y en a pas — « Invité » :
string? name = GetUserName(); // peut retourner null\nstring displayName = name ?? "Invité";\nConsole.WriteLine(displayName);\n\nSans l'opérateur ??, vous devriez écrire :
string displayName = (name != null) ? name : "Invité";\n\nReconnaissez que la première option se lit comme une phrase normale : « nom ou invité ». Joli, non ?
\n\nL'opérateur ??= : la nouvelle génération de la coalescence nulle
\n\nÀ partir de C# 8.0, l'opérateur ??= est apparu — c'est une forme abrégée d'affectation avec coalescence nulle. Il affecte la valeur de l'opérande de droite à l'opérande de gauche, uniquement si l'opérande de gauche est égal à null.
Syntaxe :
\n\nleft ??= right;\n\nCela équivaut à :
\n\nif (left == null) left = right;\n\nExemple avec ??=
\n\nList<int>? numbers = null;\nnumbers ??= new List<int>(); // numbers est maintenant = new List<int>()\nnumbers.Add(42);\nConsole.WriteLine(numbers.Count); // 1\n\nNotez : si numbers avait déjà été initialisé (non null), l'affectation n'aurait pas eu lieu. C'est idéal pour l'initialisation paresseuse.
Comparaison avec l'opérateur ternaire (? :)
\n\nBeaucoup de débutants confondent ?? avec l'opérateur ternaire ? :. Clarifions une fois pour toutes :
- \n
- L'opérateur ternaire est une forme abrégée de if-else. Il vérifie N'IMPORTE QUELLE condition booléenne :
condition ? valeur_si_vrai : valeur_si_faux. \n - L'opérateur ?? vérifie UNIQUEMENT la nullité. C'est un cas particulier, optimisé pour une seule tâche. \n
Exemple d'opérateur ternaire :
\n\nint age = 18;\nstring status = (age >= 18) ? "Adulte" : "Mineur";\n\nEt voici ce qui se passe si on essaie de remplacer ?? par un ternaire :
string? name = null;\nstring displayName = name != null ? name : "Invité"; // fonctionne, mais plus long\nstring displayName2 = name ?? "Invité"; // plus court et plus clair\n\nConclusion : utilisez ?? quand vous avez simplement besoin de substituer une valeur par défaut à la place de null. Pour toutes les autres conditions — l'opérateur ternaire.
Chaînage de l'opérateur ??
\n\nVous pouvez enchaîner plusieurs opérateurs ??. C'est pratique lorsqu'il y a plusieurs sources possibles de valeur :
string? firstChoice = GetFromCache