1. Introduction
Tu sais déjà écrire ce genre de code :
switch (color)
{
case "red":
Console.WriteLine("Stop !");
break;
case "yellow":
Console.WriteLine("Attends...");
break;
case "green":
Console.WriteLine("Tu peux y aller !");
break;
default:
Console.WriteLine("C’est quoi cette couleur ?");
break;
}
Mais si on veut affecter à une variable une valeur différente selon le paramètre d’entrée, genre retourner une chaîne basée sur un nombre depuis une fonction ? Avant l’apparition des switch-expressions, on devait bricoler des trucs comme ça :
string meaning;
switch (number)
{
case 42:
meaning = "La réponse à la grande question sur la vie, l’univers et tout le reste";
break;
case 7:
meaning = "Nombre porte-bonheur";
break;
default:
meaning = "Nombre ordinaire";
break;
}
Pas super élégant pour un langage du XXIe siècle, non ? On aimerait bien retourner direct la valeur, comme dans les langages fonctionnels.
C’est là que débarquent les switch-expressions — une des features les plus stylées (et récentes) de C#, à partir de la version 8.0.
2. switch-expressions : une syntaxe à câliner
Comparons : statement vs expression
Le switch classique, c’est un statement ("instruction"), alors que la switch-expression est une expression, c’est-à-dire qu’elle calcule une valeur qu’on peut direct affecter à une variable ou retourner depuis une méthode.
Structure d’une switch-expression :
var result = value switch
{
pattern1 => expression1,
pattern2 => expression2,
_ => defaultExpression // "underscore" - c’est "sinon"
};
Par exemple :
int number = 42;
string meaning = number switch
{
42 => "La réponse à la grande question sur la vie, l’univers et tout le reste",
7 => "Nombre porte-bonheur",
_ => "Nombre ordinaire"
};
Console.WriteLine(meaning); // => La réponse à la grande question sur la vie, l’univers et tout le reste
C’est super concis, lisible, pas de code spaghetti, pas un seul break;.
À noter : l’underscore _ — c’est "attraper tous les autres cas", l’équivalent de default.
3. switch-expressions et patterns : comment ça marche ensemble
C’est là que ça devient fun. Dans les switch-expressions, tu peux utiliser non seulement des valeurs classiques, mais aussi des patterns : tests sur des intervalles, des types, des propriétés d’objets, de la déconstruction (découper un objet en morceaux), et même des combinatorial patterns (and, or, not).
Exemples de patterns dans une switch-expression
Patterns constants
C’est ce qu’on a déjà fait plus haut : comparer à 42, 7, etc.
Intervalles et comparaisons
int age = 17;
string category = age switch
{
< 18 => "Mineur",
>= 18 and <= 65 => "Adulte",
> 65 => "Personne âgée",
_ => "Catégorie d’âge inconnue"
};
Console.WriteLine(category);
Au fait, tu vois — on peut utiliser plusieurs conditions ensemble ! C# devient de plus en plus expressif.
Patterns de type (Type Patterns)
Imaginons qu’on a un objet qui peut être de différents types (genre object value;). On peut gérer les différents types comme ça :
object value = 3.14;
string description = value switch
{
int i => $"Nombre entier : {i}",
double d => $"Nombre à virgule : {d:F2}",
string s => $"C’est une chaîne : '{s}'",
null => "null !",
_ => "Autre chose"
};
Console.WriteLine(description); // => Nombre à virgule : 3.14
Patterns liés (Property Patterns et Positional Patterns)
Depuis C# 8 et après, on peut tester les valeurs des propriétés direct dans la switch-expression.
Exemple avec un objet
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
User user = new User { Name = "Anna", Age = 17 };
string welcome = user switch
{
{ Age: < 18 } => $"Salut, {user.Name} ! Tu es ado.",
{ Age: >= 18 and <= 65 } => $"Coucou, {user.Name} ! La vie adulte est géniale.",
{ Age: > 65 } => $"Bienvenue, {user.Name} ! On est toujours content de te voir.",
_ => "Âge inconnu"
};
Console.WriteLine(welcome);
Ici, entre accolades { Age: < 18 } — c’est un property pattern, donc on teste pas tout l’objet, juste sa propriété.
4. Nouveaux patterns C# 11-14
C# vise la concision et la flexibilité. Récemment, il a eu les combinatorial patterns : and, or, not, et les positional patterns sont devenus encore meilleurs. On va voir ça.
Patterns logiques : and, or, not
Tu peux faire des conditions complexes, comme en logique mathématique !
int temperature = 25;
string result = temperature switch
{
< 0 => "Il gèle !",
>= 0 and < 20 => "Frais",
>= 20 and < 30 => "Confortable",
>= 30 or <= -30 => "Extrême !",
_ => "Température bizarre"
};
Si tu veux exclure des cas, pas de souci :
int score = 80;
string grade = score switch
{
>= 90 => "Excellent",
>= 60 and not >= 90 => "Bien",
_ => "Mauvais"
};
Déconstruction (Positional Patterns)
Si tu as une struct ou un record qui supporte la déconstruction, C# te permet de découper l’objet direct dans la switch-expression :
public record Point(int X, int Y);
Point p = new Point(10, 20);
string desc = p switch
{
(0, 0) => "Origine",
(var x, 0) => $"Sur l’axe X, X={x}",
(0, var y) => $"Sur l’axe Y, Y={y}",
(var x, var y) when x == y => $"Sur la diagonale : {x}",
_ => $"Au point ({p.X}, {p.Y})"
};
Console.WriteLine(desc); // => Au point (10, 20)
5. Quand et pourquoi utiliser les switch-expressions
Dans le C# moderne, les switch-expressions — ce n’est pas juste une "feature" à la mode, c’est un vrai moyen d’éviter le code verbeux, de rendre ton code plus compact, plus facile à tester et à maintenir. C’est super important quand tu écris des parseurs, des gestionnaires de commandes, de la logique métier, des règles de config — partout où tu dois dispatcher selon des critères complexes, pas seulement des valeurs, mais aussi des types, des intervalles, des propriétés, des combinaisons.
En entretien
- Comment tu gères différentes réponses d’un utilisateur ?
- Comment tu fais pour retourner une valeur de fonction qui dépend à la fois du type et de la valeur ?
- Comment tu ajoutes facilement de nouvelles règles sans une tonne de if-else ?
Montre une switch-expression avec des patterns ! Ça montre direct que tu connais les nouveautés du langage et que tu as un bon style de code.
Tableau : comparaison entre switch-statement et switch-expression
| Caractéristique | switch statement | switch expression |
|---|---|---|
| Type | instruction (statement) | expression |
| Utilisation de break | obligatoire | pas besoin |
| Peut retourner une valeur | seulement via une variable | oui, retourne direct la valeur |
| Peut utiliser des patterns | partiellement | complètement (type, propriété, etc.) |
| Piège | on peut oublier break | tous les chemins doivent retourner une valeur |
6. Erreurs typiques et petites galères
- Les débutants confondent souvent la différence entre le switch-statement ("instruction") et la switch-expression ("expression"). Par exemple, ils oublient que dans une switch-expression il ne faut pas de break;, et que toutes les branches doivent absolument retourner une valeur.
- Si tu oublies la branche _, le compilateur va te dire : "et si rien ne correspond ?".
- Dans une switch-expression tu ne peux pas utiliser goto (et tant mieux !).
- Si tu mets deux fois la même condition (genre deux patterns identiques), le compilateur ne laissera pas passer non plus.
- Fais gaffe au type de la valeur retournée par la switch-expression : il doit être compatible avec le type de la variable à laquelle tu l’affectes.
GO TO FULL VERSION