Modèles relationnels, logiques et entre parenthèses

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#. Commencez par la vue d’ensemble des critères correspondants si les modèles sont nouveaux pour vous. Pour obtenir des règles de langage complètes, consultez les modèles relationnels et les modèles logiques dans la référence de langage.

Les modèles relationnels et logiques décrivent les plages, les alternatives et les exclusions. La méthode suivante les combine pour classifier une température :

static string ClassifyTemperature(int temperature) =>
    temperature switch
    {
        < 0 => "Below freezing",
        >= 18 and <= 24 => "Comfortable",
        (>= 0 and < 10) or > 30 => "Far outside the comfortable range",
        _ => "Cool or warm"
    };

L’expression temperature est l’entrée du motif. C# l’évalue une fois, et chaque bras de commutateur teste la valeur résultante. Les bras illustrent ces tests :

  • < 0 vérifie une valeur limite.
  • >= 18 and <= 24 teste une plage de valeurs.
  • (>= 0 and < 10) or > 30 teste deux plages alternatives.

Cet article présente à la fois des modèles et des conditions impératives afin que vous puissiez apprendre chaque formulaire et comparer la façon dont ils expriment les mêmes décisions. Une seule condition peut ressembler à l’une ou l’autre des formes. Les modèles peuvent faciliter la lecture d’une série de branches connexes en conservant les choix en regard de leurs résultats. Choisissez le formulaire qui facilite la compréhension du code.

Comparer des valeurs avec des modèles relationnels

Un motif relationnel compare l’entrée du motif à une constante connue à la compilation à l’aide de <, >, <= ou >=. Une constante au moment de la compilation est une valeur que le compilateur peut évaluer lors de la compilation du programme. Les littéraux numériques et de caractères, ainsi que les variables const de types numériques ou de caractères compatibles, constituent des exemples représentatifs. Les variables, propriétés, appels de méthode et static readonly champs ordinaires ne sont pas des constantes au moment de la compilation. Dans l’exemple d’ouverture, >= 18 et <= 24 testent tous deux la même valeur temperature évaluée.

Le même symbole relationnel peut apparaître dans une expression ordinaire ou dans un modèle. L’exemple suivant utilise les deux formes avec une température :

static void ShowExpressionAndPattern(int temperature, int threshold)
{
    bool belowThreshold = temperature < threshold;
    bool belowFreezing = temperature is < 0;

    string description = temperature switch
    {
        < 0 => "Freezing",
        0 => "Freezing point",
        > 0 => "Above freezing"
    };

    Console.WriteLine(
        $"Below threshold: {belowThreshold}; " +
        $"below freezing: {belowFreezing}; {description}");
}

temperature < threshold est une expression relationnelle. Il évalue les deux opérandes et produit un bool. L’un ou l’autre opérande peut être une expression nonconstante.

Dans temperature is < 0, temperature est l’expression d’entrée de modèle. C# l’évalue et le modèle < 0 relationnel teste la valeur résultante. Dans la branche switch < 0 => "Freezing", l’expression située avant switch fournit l’entrée, de sorte que le motif contient uniquement < 0.

L’expression peut être comparée temperature à la variable threshold. Un opérande de modèle relationnel doit être une constante au moment de la compilation. Utilisez donc l’expression relationnelle lorsque la valeur de comparaison est une variable. Lorsque la valeur de comparaison est constante, l’un ou l’autre formulaire peut fonctionner.

Lorsque l’opérande approprié est constant, choisissez principalement pour la lisibilité. Une expression relationnelle correspond souvent à une comparaison directe. Un modèle relationnel se compose d’autres modèles et s’adapte naturellement quand plusieurs plages mappent pour changer de résultat.

Combiner des conditions avec des modèles logiques

Les modèles logiques combinent ou annulent les modèles avec les opérateurs andde modèle , oret not:

  • Un motif and correspond si les deux motifs imbriqués correspondent.
  • Un modèle or correspond lorsque l’un des modèles imbriqués correspond.
  • Un not modèle réussit lorsque son modèle imbriqué échoue.

L’exemple d’ouverture utilise and pour décrire une plage et or décrire des alternatives. Un not modèle peut exclure une valeur, comme dans status is not Status.Complete. Les méthodes suivantes présentent les deux formulaires afin que vous puissiez apprendre leur syntaxe et comparer la façon dont ils expriment le même test :

static bool IsWeekendPattern(DayOfWeek day) =>
    day is DayOfWeek.Saturday or DayOfWeek.Sunday;

static bool IsWeekendImperative(DayOfWeek day) =>
    day == DayOfWeek.Saturday || day == DayOfWeek.Sunday;

Le formulaire de modèle utilise deux modèles constants joints par or. La forme impérative utilise deux expressions d’égalité reliées par l’opérateur OU conditionnel ||. Les deux formulaires sont concis et clairs pour cette condition unique. Choisissez le formulaire qui correspond le mieux au code environnant. Les modèles clarifient souvent plusieurs choix connexes dans un switch, comme dans l’exemple d’ouverture.

Les opérateurs de modèle forment des modèles plutôt que des expressions booléennes : and correspond à la combinaison de modèles, or aux alternatives de modèle et not à la négation de modèle. Les expressions booléennes utilisent &&, ||et !. Choisissez or quand plusieurs alternatives de modèle ont le même résultat. Choisissez not lorsqu’il est plus clair d’exprimer le motif à exclure que d’énumérer toutes les valeurs acceptées.

Modèles de groupe avec parenthèses

Un motif parenthésé utilise des parenthèses pour indiquer ou modifier la façon dont les motifs imbriqués sont regroupés. La liaison détermine le modèle d’opérandes qu’un opérateur regroupe, similaire au regroupement implicite lorsque vous n’écrivez pas de parenthèses. C# spécifie l’ordre de liaison suivant :

  1. not
  2. and
  3. or

Le test suivant accepte les priorités 1 à 3 ou la priorité spéciale 9 :

static bool IsAcceptedPriority(int priority) =>
    priority is (>= 1 and <= 3) or 9;

Les groupes and de compilateurs avant or. Les parenthèses rendent le regroupement prévu explicite et les deux alternatives faciles à voir : la plage comprise entre 1 et 3 ou 9. Pour une lisibilité, utilisez des parenthèses chaque fois qu’un modèle mélange and et or, ou lorsqu’il not s’applique à un modèle composé. Les parenthèses peuvent également modifier le regroupement par défaut, comme dans not (>= 1 and <= 3).

L’ordre de vérification du runtime pour les modèles imbriqués n’est pas spécifié, et les opérateurs de modèle suivent des règles de correspondance de modèle plutôt que des règles booléennes à court-circuit. Écrivez des modèles imbriqués afin que leur résultat soit indépendant de l’ordre de vérification.

Utiliser une clause de garde when pour une condition séparée

Les modèles logiques fonctionnent mieux lorsque les modèles imbriqués décrivent la valeur d’entrée elle-même. Un when garde est une condition booléenne supplémentaire sur une case étiquette ou un bras de commutateur. Utilisez un garde lorsque la décision dépend également d’informations distinctes de l’entrée du modèle.

L’avertissement suivant dépend de la température et d’une valeur distincte isOutdoors :

static string GetHeatWarning(int temperature, bool isOutdoors) =>
    temperature switch
    {
        > 35 when isOutdoors => "High heat outdoors",
        > 35 => "High heat",
        _ => "No heat warning"
    };

Le modèle > 35 relationnel décrit l’entrée temperature . Le garde when isOutdoors vérifie une valeur distincte. Un garde est également préférable lorsque la condition a besoin d’un appel de méthode ou d’une expression booléenne que la syntaxe du modèle n’exprime pas clairement.

Utilisez des modèles relationnels et logiques lorsqu’ils rendent les formes ou valeurs autorisées de l’entrée plus faciles à voir, en particulier entre plusieurs bras de commutateur. Utilisez une expression booléenne ordinaire lorsqu’elle indique une condition directe plus simplement. Utilisez un when garde lorsqu’un choix de commutateur dépend d’une valeur distincte ou d’une condition mieux exprimée en tant qu’expression booléenne.

Voir aussi