Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Tip
Cet article fait partie de la section Notions de base pour les développeurs qui connaissent déjà au moins un langage de programmation et apprennent C#. Si vous débutez avec la programmation, commencez par commencer par les didacticiels De prise en main .
Venant d’une autre langue ? Les expressions en C# fonctionnent autant que dans Java, C++et JavaScript. Une différence qui vaut la peine de noter : les opérateurs d’affectation composée comme += et l’opérateur ++ d’incrément sont des expressions en C#, afin qu’ils puissent apparaître dans des expressions plus grandes.
Une expression est un élément de code que le compilateur évalue pour produire une valeur : un nombre, une chaîne, une référence ou un bool. Par exemple, 3 + 4 * 2 est une expression qui s’évalue à l’entier 11, et total > 10 est une expression qui s’évalue à true ou false.
Les expressions les plus simples sont des littéraux (comme 42 ou "hello") et des noms de variables (comme total). Vous créez des expressions plus complexes en combinant des expressions plus simples avec des opérateurs.
Expressions et déclarations
Une expression produit une valeur. Une instruction est une instruction complète que le programme exécute. De nombreuses instructions contiennent des expressions. Par exemple, int total = 3 + 4 * 2; est une instruction de déclaration de variable. Le compilateur évalue l’expression 3 + 4 * 2d’initialiseur, qui produit 11, et affecte cette valeur à la nouvelle variable total.
Vous pouvez considérer une expression comme une expression et une instruction C# comme une phrase complète. Ces définitions de travail vous aident à comprendre la terminologie et les explications formelles que vous rencontrerez lorsque vous en apprendrez davantage sur C#, bien que le codage ordinaire vous oblige rarement à vous souvenir de la distinction consciemment.
Combinaison d’expressions
Les expressions peuvent être combinées. Prenez le cas de 3 + 4 * 2. Cette expression unique contient en fait deux expressions plus petites : l’expression 4 * 2de multiplication et l’expression 3 + <result>d’ajout. Lorsque les expressions sont combinées, C# a besoin d’une règle pour déterminer celle à évaluer en premier. Cette règle est la priorité de l’opérateur.
Vous n’avez pas besoin de mémoriser la hiérarchie de priorité complète. La section suivante récapitule les groupes quotidiens et les parenthèses vous permettent toujours de rendre l’ordre explicite lorsque vous n’êtes pas sûr.
Précédence des opérateurs
La priorité des opérateurs détermine comment une expression combinée se regroupe en sous-expressions. Ce concept est similaire aux règles d’ordre des opérations de la classe mathématique. Un opérateur avec une priorité plus élevée se lie plus étroitement à ses opérandes. L’expression est structurée comme si ces opérandes étaient regroupés entre parenthèses. Dans 3 + 4 * 2, * a une priorité supérieure à +, donc les groupes d’expressions comme 3 + (4 * 2), et non (3 + 4) * 2.
C# a plus de groupes de priorité que les quatre résumés ici. Ces groupes supplémentaires appliquent des règles familières( par exemple, la multiplication avant l’ajout) et couvrent l’ensemble complet d’opérateurs. Les groupes suivants couvrent ce que vous rencontrez le plus souvent dans le code quotidien :
-
Principal, unaire et plage : il s’agit de trois groupes de précédence distincts, qui sont tous liés plus étroitement que l’arithmétique. Ce résumé les combine en une seule étape, car, à des fins pratiques, ils s’appliquent tous avant arithmétique.
-
Opérateurs primaires — accès aux membres (
x.y), appels de méthode (f()), indexation (a[i]) et accès conditionnel par valeur null (?.,?[]) — sont ceux dont la liaison est la plus forte. -
Les opérateurs unaires agissent sur un opérande unique : négation (
-x), NOT logique (!flag), incrément de préfixe (++i) et incrément postfix (i++). - L’opérateur de plage (
..) génère des plages d’index pour les expressions de tranche, commearray[1..4].
-
Opérateurs primaires — accès aux membres (
-
Arithmétique —
*,/,%ont une priorité plus élevée que+et-. La multiplication et la division se produisent avant l’addition et la soustraction. -
Comparaison —
<,>,<=,>=,==,!=ont une priorité inférieure à l’arithmétique ; les opérations arithmétiques s’effectuent donc avant la comparaison. -
Logique :
&&et||liez moins étroitement les opérateurs communs, de sorte que les comparaisons se terminent avant la combinaison logique.
Cette précédence signifie que l’expression score + bonus > threshold && attempts < maxAttempts évalue exactement comme vous l’avez lu : ajouter score etbonus, comparer la somme à threshold, comparer à maxAttempts, combiner attempts les deux bool résultats avec &&. L’ajout de parenthèses pour rendre chaque regroupement explicite affiche la même structure : ((score + bonus) > threshold) && (attempts < maxAttempts).
Pour obtenir la hiérarchie de priorité complète couvrant chaque opérateur, consultez les opérateurs et expressions C#.
Utiliser des parenthèses pour rendre l’intention claire
Les parenthèses remplacent la priorité et documentent votre intention en même temps. Lorsque l’ordre n’est pas évident dans les groupes ci-dessus, ajoutez des parenthèses :
int score = 80;
int bonus = 15;
int threshold = 90;
bool eligible = true;
// Without parentheses: || binds less tightly than &&, so this reads as:
// eligible && (score + bonus > threshold) || bonus > 20
bool result1 = eligible && score + bonus > threshold || bonus > 20;
// With parentheses: forces the || to combine two complete conditions
bool result2 = (eligible && score + bonus > threshold) || bonus > 20;
Console.WriteLine(result1); // => True
Console.WriteLine(result2); // => True
// Parentheses can also change the result:
bool isAdmin = false;
bool isOwner = true;
// Without: && binds tighter, so: (isAdmin && isOwner) || true
bool access1 = isAdmin && isOwner || true;
// With: forces the || to run first
bool access2 = isAdmin && (isOwner || true);
Console.WriteLine(access1); // => True (false && true is false; false || true is true)
Console.WriteLine(access2); // => False (false && anything is false)
Les deux dernières lignes montrent que les parenthèses peuvent modifier le résultat, pas seulement le style. Quand && et || s’affichent ensemble, ajoutez des parenthèses pour expliquer la condition qui se combine en premier. Un lecteur qui voit (isAdmin && isOwner) || isSuperUser comprend immédiatement l’intention.
Comment les expressions sont évaluées
Comprendre comment C# évalue les expressions combinées est plus facile avec une analogie. Pensez à travailler à travers un problème mathématique complexe avec crayon et papier : vous identifiez la sous-expression la plus haute ou la plus prioritaire, calculez sa valeur intermédiaire, notez le résultat, puis répétez avec la sous-expression suivante , en continuant jusqu’à atteindre la réponse finale.
C# suit le même processus, guidé par deux règles :
Règle 1 : les opérandes sont évalués de gauche à droite. Pour toute expression binaire, les deux opérandes doivent être entièrement évalués avant l’application de l’opérateur. C# évalue d’abord l’opérande gauche, puis la droite, puis effectue l’opération.
Règle 2 : certains opérateurs utilisent l’évaluation de court-circuit. Certains opérateurs arrêtent d’évaluer dès que le résultat est déterminé, en ignorant les opérandes restants :
-
&&(AND conditionnel) : retournefalsedès que le côté gauche estfalse. Le côté droit n’est jamais évalué. -
||(OR conditionnel) : retournetruedès que le côté gauche esttrue. Le côté droit n’est jamais évalué. -
?:(conditionnel/ternaire) : évalue uniquement la branche qui correspond à la condition : l’autre branche n’est jamais évaluée. -
?.(accès conditionnel Null à un membre) et?[](accès conditionnel Null à un élément) : arrêtent l’évaluation et renvoient immédiatementnulllorsque le côté gauche estnull, sans effectuer l’accès au membre ni à l’index. -
??=(affectation de coalescence Null) : affecte le côté droit uniquement lorsque le côté gauche estnull.
Évaluation sur papier et au crayon
Considérez l’expression 3 + 6 / 2. Même si l’ajout apparaît en premier dans l’ordre de lecture, / a une priorité plus élevée que +, il s’agit donc 6 / 2 de la sous-expression qui évalue en premier. Travailler pas à pas , exactement comme vous le feriez sur papier :
3 + 6 / 2
↓ (evaluate 6 / 2 → 3)
3 + 3
↓ (evaluate 3 + 3 → 6)
6
// 3 + 6 / 2
// Step 1: 6 / 2 has higher precedence → interim value 3
// Step 2: 3 + 3 → final result 6
int result = 3 + 6 / 2;
Console.WriteLine(result); // => 6
La valeur 3 intermédiaire produite par 6 / 2 devient l’opérande droit de +, et le résultat final est 6. Chaque sous-expression produit une valeur intermédiaire ; ces valeurs intermédiaires alimentent la sous-expression suivante, jusqu’à ce qu’une seule valeur reste.
L’associativité est un concept connexe : lorsque deux opérateurs ont la même priorité, l’associativité décide celle qui va en premier. La plupart des opérateurs C# sont associatifs à gauche, ce qui signifie qu’ils sont regroupés de gauche à droite. Donc a - b - c , c’est la même chose que (a - b) - c, pas a - (b - c).
Évaluation de court-circuit en pratique
L’évaluation à court-circuit est particulièrement utile pour les tests de nullité :
string? text = null;
// Safe: second condition runs only when text is not null
bool hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => False (short-circuits after null check; no NullReferenceException)
text = "hello";
hasContent = text != null && text.Length > 0;
Console.WriteLine(hasContent); // => True
// || short-circuits on true: right side is never evaluated when left side is true
string word = "hello";
bool anyMatch = word.StartsWith("h") || word.StartsWith("x");
Console.WriteLine(anyMatch); // => True (right side never evaluated)
// ?. short-circuits on null: returns null without accessing .Length
string? maybeNull = null;
int? length = maybeNull?.Length; // length is null; no NullReferenceException
Console.WriteLine(length.HasValue); // => False
text != null && text.Length > 0 est sûr, car la deuxième condition s’exécute uniquement quand text n’est pas null. De même, ?. arrête l’évaluation lorsqu’elle rencontre une référence null, ce qui évite un NullReferenceException sans vérification explicite de if.
Pour un aperçu plus large des opérateurs avec protection contre les valeurs nulles, consultez les opérateurs de valeur null en C#.
Voir aussi
- Opérateurs et expressions C# (référence de langage) : table de priorité complète et chaque opérateur
- Opérateurs arithmétiques, de comparaison, logiques et d’affectation : les opérateurs quotidiens en profondeur
-
Comparaisons d’égalité : comment
==,!=etEqualsfonctionnent -
Opérateurs Null en C# —
?.,??et??= - Opérateurs logiques booléens