switch (référence C#)switch (C# Reference)

switch est une instruction de sélection qui choisit une section de commutation unique à exécuter à partir d’une liste de candidats en fonction d’une mise en correspondance de modèle avec l’expression de correspondance.switch is a selection statement that chooses a single switch section to execute from a list of candidates based on a pattern match with the match expression.

using System;

public class Example
{
   public static void Main()
   {
      int caseSwitch = 1;
      
      switch (caseSwitch)
      {
          case 1:
              Console.WriteLine("Case 1");
              break;
          case 2:
              Console.WriteLine("Case 2");
              break;
          default:
              Console.WriteLine("Default case");
              break;
      }
   }
}
// The example displays the following output:
//       Case 1

L’instruction switch est souvent utilisée comme alternative à une construction if-else si une expression unique est testée en fonction de trois conditions ou plus.The switch statement is often used as an alternative to an if-else construct if a single expression is tested against three or more conditions. Par exemple, l’instruction switch suivante détermine laquelle des trois valeurs possibles a été affectée à une variable de type Color :For example, the following switch statement determines whether a variable of type Color has one of three values:

using System;

public enum Color { Red, Green, Blue }

public class Example
{
   public static void Main()
   {
      Color c = (Color) (new Random()).Next(0, 3);
      switch (c)
      {
         case Color.Red:
            Console.WriteLine("The color is red");
            break;
         case Color.Green:
            Console.WriteLine("The color is green");
            break;
         case Color.Blue:
            Console.WriteLine("The color is blue");   
            break;
         default:
            Console.WriteLine("The color is unknown.");
            break;   
      }
   }
}

Il est équivalent à l’exemple suivant qui utilise une construction if -else.It is equivalent to the following example that uses an if-else construct.

using System;

public enum Color { Red, Green, Blue }

public class Example
{
   public static void Main()
   {
      Color c = (Color) (new Random()).Next(0, 3);
      if (c == Color.Red)
         Console.WriteLine("The color is red");
      else if (c == Color.Green)
         Console.WriteLine("The color is green");
      else if (c == Color.Blue)
         Console.WriteLine("The color is blue");   
      else
         Console.WriteLine("The color is unknown.");
   }
}
// The example displays the following output:
//       The color is red

Expression de correspondanceThe match expression

L’expression de correspondance fournit la valeur à mettre en correspondance avec les modèles dans les étiquettes case.The match expression provides the value to match against the patterns in case labels. Sa syntaxe est la suivante :Its syntax is:

   switch (expr)

En C# 6, l’expression de correspondance doit être une expression qui retourne une valeur d’un des types suivants :In C# 6, the match expression must be an expression that returns a value of the following types:

À compter de C# 7.0, l’expression de correspondance peut être toute expression non Null.Starting with C# 7.0, the match expression can be any non-null expression.

Section de commutationThe switch section

Une instruction switch inclut une ou plusieurs sections de commutation.A switch statement includes one or more switch sections. Chaque section de commutation contient une ou plusieurs étiquettes case suivies d’une ou de plusieurs instructions.Each switch section contains one or more case labels followed by one or more statements. L'exemple suivant montre une instruction switch simple qui a trois sections switch.The following example shows a simple switch statement that has three switch sections. Chaque section switch a un nom de cas, tel que case 1: et une liste de deux instructions.Each switch section has one case label, such as case 1:, and two statements.

Une instruction switch peut inclure un nombre quelconque de sections de commutation, et chaque section peut contenir une ou plusieurs étiquettes case, comme dans l’exemple ci-dessous.A switch statement can include any number of switch sections, and each section can have one or more case labels, as shown in the following example. Toutefois, deux étiquettes case ne doivent pas contenir la même expression.However, no two case labels may contain the same expression.

using System;

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      int caseSwitch = rnd.Next(1,4);
      
      switch (caseSwitch)
      {
          case 1:
              Console.WriteLine("Case 1");
              break;
          case 2:
          case 3:
              Console.WriteLine($"Case {caseSwitch}");
              break;
          default:
              Console.WriteLine($"An unexpected value ({caseSwitch})");
              break;
      }
   }
}
// The example displays output like the following:
//       Case 1

Une seule section de commutation s’exécute dans une instruction switch.Only one switch section in a switch statement executes. C# ne permet pas à l’exécution de passer d’une section switch à la suivante.C# does not allow execution to continue from one switch section to the next. Pour cette raison, le code suivant génère une erreur du compilateur, CS0163 : « Le contrôle ne peut pas passer d’une étiquette case () à une autre ».Because of this, the following code generates a compiler error, CS0163: "Control cannot fall through from one case label () to another."

switch (caseSwitch)  
{  
    // The following switch section causes an error.  
    case 1:  
        Console.WriteLine("Case 1...");  
        // Add a break or other jump statement here.  
    case 2:  
        Console.WriteLine("... and/or Case 2");  
        break;  
}  

Si cela est nécessaire, il est possible de procéder en quittant explicitement la section de commutation à l’aide d’une instruction break, goto ou return.This requirement is usually met by explicitly exiting the switch section by using a break, goto, or return statement. Toutefois, le code suivant est également valide, car il garantit que le contrôle du programme ne peut pas passer à la section de commutation default.However, the following code is also valid, because it ensures that program control cannot fall through to the default switch section.

switch (caseSwitch)  
{  
    // The following switch section causes an error.  
    case 1:  
        Console.WriteLine("Case 1...");  
        break;  
    case 2:  
    case 3:
        Console.WriteLine("... and/or Case 2");  
        break;
    case 4:  
        while (true)  
           Console.WriteLine("Endless looping. . . ."); 
    default:
        Console.WriteLine("Default value...");
        break;                 
}  

L’exécution de la liste d’instructions dans la section de commutation avec une étiquette case qui correspond à l’expression de correspondance commence avec la première instruction et continue en suivant la liste d’instructions, en général jusqu’à ce qu’une instruction de saut, telle que break, goto case, goto label, return ou throw, soit atteinte.Execution of the statement list in the switch section with a case label that matches the match expression begins with the first statement and proceeds through the statement list, typically until a jump statement, such as a break, goto case, goto label, return, or throw, is reached. À ce stade, le contrôle est transféré hors de l'instruction switch ou vers un autre nom de cas.At that point, control is transferred outside the switch statement or to another case label. Si une instruction goto est utilisée, elle doit transférer le contrôle à une étiquette constante.A goto statement, if it is used, must transfer control to a constant label. Cette restriction est nécessaire, car tenter de transférer le contrôle à une étiquette non constante peut avoir des effets indésirables, tels que le transfert du contrôle à un emplacement inattendu dans le code ou la création d’une boucle sans fin.This restriction is necessary, since attempting to transfer control to a non-constant label can have undesirable side-effects, such transferring control to an unintended location in code or creating an endless loop.

Étiquettes caseCase labels

Chaque étiquette case spécifie un modèle à comparer à l’expression de correspondance (la variable caseSwitch dans les exemples précédents).Each case label specifies a pattern to compare to the match expression (the caseSwitch variable in the previous examples). S’ils correspondent, le contrôle est transféré à la section de commutation qui contient la première étiquette case correspondante.If they match, control is transferred to the switch section that contains the first matching case label. Si aucun modèle d’étiquette case ne correspond à l’expression de correspondance, le contrôle est transféré à la section avec l’étiquette case default, si une telle section existe.If no case label pattern matches the match expression, control is transferred to the section with the default case label, if there is one. En l’absence d’étiquette case default, aucune instruction d’aucune section de commutation n’est exécutée et le contrôle est transféré hors de l’instruction switch.If there is no default case, no statements in any switch section are executed, and control is transferred outside the switch statement.

Pour plus d’informations sur l’instruction switch et les critères spéciaux, consultez la section Critères spéciaux avec l’instruction switch.For information on the switch statement and pattern matching, see the Pattern matching with the switch statement section.

Étant donné que C# 6 prend en charge uniquement le modèle de constante et n’autorise pas la répétition des valeurs constantes, les étiquettes case définissent des valeurs qui s’excluent mutuellement, et un seul modèle peut correspondre à l’expression de correspondance.Because C# 6 supports only the constant pattern and does not allow the repetition of constant values, case labels define mutually exclusive values, and only one pattern can match the match expression. Par conséquent, l’ordre dans lequel les instructions case apparaissent n’a pas d’importance.As a result, the order in which case statements appear is unimportant.

Dans C# 7.0, toutefois, comme d’autres modèles sont pris en charge, les étiquettes case ne sont pas tenues de définir des valeurs s’excluant mutuellement et plusieurs modèles peuvent correspondre à l’expression de correspondance.In C# 7.0, however, because other patterns are supported, case labels need not define mutually exclusive values, and multiple patterns can match the match expression. Comme seules les instructions de la section de commutation contenant le premier modèle correspondant sont exécutées, l’ordre dans lequel les instructions case apparaissent est désormais important.Because only the statements in the switch section that contains the first matching pattern are executed, the order in which case statements appear is now important. Si C# détecte une section de commutation dont la ou les instructions case sont équivalentes aux instructions précédentes, ou en sont des sous-ensembles, C# génère une erreur du compilateur, CS8120, « Le switch case a déjà été pris en charge par un case antérieur ».If C# detects a switch section whose case statement or statements are equivalent to or are subsets of previous statements, it generates a compiler error, CS8120, "The switch case has already been handled by a previous case."

L’exemple suivant illustre une instruction switch qui utilise divers modèles ne s’excluant pas mutuellement.The following example illustrates a switch statement that uses a variety of non-mutually exclusive patterns. Si vous déplacez la section de commutation case 0: pour qu’elle ne soit plus la première section dans l’instruction switch, C# génère une erreur du compilateur, car un entier dont la valeur est égale à zéro est un sous-ensemble de tous les entiers, ce qui est le modèle défini par l’instruction case int val.If you move the case 0: switch section so that it is no longer the first section in the switch statement, C# generates a compiler error because an integer whose value is zero is a subset of all integers, which is the pattern defined by the case int val statement.

using System;
using System.Collections.Generic;
using System.Linq;

public class Example
{
   public static void Main()
   {
      var values = new List<object>();
      for (int ctr = 0; ctr <= 7; ctr++) {
         if (ctr == 2) 
            values.Add(DiceLibrary.Roll2());
         else if (ctr == 4)
            values.Add(DiceLibrary.Pass());
         else   
            values.Add(DiceLibrary.Roll());
      }   

      Console.WriteLine($"The sum of { values.Count } die is { DiceLibrary.DiceSum(values) }");
   }
}

public static class DiceLibrary
{
   // Random number generator to simulate dice rolls.
   static Random rnd = new Random();

   // Roll a single die.
   public static int Roll()
   {
      return rnd.Next(1, 7);
   }

   // Roll two dice.
   public static List<object> Roll2()
   {
      var rolls = new List<object>();      
      rolls.Add(Roll());
      rolls.Add(Roll());
      return rolls;
   }

   // Calculate the sum of n dice rolls.
   public static int DiceSum(IEnumerable<object> values)
   {
      var sum = 0;
      foreach (var item in values)
      {
            switch (item)
            {
               // A single zero value.
               case 0:
                  break;
               // A single value.
               case int val:
                  sum += val;
                  break;
               // A non-empty collection.
               case IEnumerable<object> subList when subList.Any():
                  sum += DiceSum(subList);
                  break;
               // An empty collection.
               case IEnumerable<object> subList:
                  break;
               //  A null reference.
               case null:
                  break;
               // A value that is neither an integer nor a collection.
               default:
                  throw new InvalidOperationException("unknown item type");
            }
      }
      return sum;
   }

   public static object Pass()
   {
      if (rnd.Next(0, 2) == 0)
         return null;
      else
         return new List<object>();
   }
}

Vous pouvez corriger ce problème et éliminer l’avertissement du compilateur de deux façons :You can correct this issue and eliminate the compiler warning in one of two ways:

  • en modifiant l’ordre des sections de commutation ;By changing the order of the switch sections.

  • en utilisant une clause when dans l’étiquette case.By using a when clause in the case label.

Étiquette case defaultThe default case

L’étiquette case default spécifie la section de commutation à exécuter si l’expression de correspondance ne correspond à aucune autre étiquette case.The default case specifies the switch section to execute if the match expression does not match any other case label. En l’absence d’une étiquette case default, si l’expression de correspondance ne correspond à aucune autre étiquette case, le flux de programme traverse l’instruction switch.If a default case is not present and the match expression does not match any other case label, program flow falls through the switch statement.

L’étiquette case default peut apparaître à n’importe quelle position dans l’instruction switch.The default case can appear in any order in the switch statement. Quelle que soit sa position dans le code source, elle est toujours évaluée en dernier, une fois que toutes les étiquettes case ont été évaluées.Regardless of its order in the source code, it is always evaluated last, after all case labels have been evaluated.

Critères spéciaux avec l’instruction switch Pattern matching with the switch statement

Chaque instruction case définit un modèle qui, s’il correspond à l’expression de correspondance, entraîne l’exécution de la section de commutation qui le contient.Each case statement defines a pattern that, if it matches the match expression, causes its containing switch section to be executed. Toutes les versions de C# prennent en charge le modèle de constante.All versions of C# support the constant pattern. Les autres modèles sont pris en charge à compter de C# 7.0.The remaining patterns are supported beginning with C# 7.0.

Modèle de constanteConstant pattern

Le modèle de constante teste si l’expression de correspondance est égale à une constante spécifiée.The constant pattern tests whether the match expression equals a specified constant. Sa syntaxe est la suivante :Its syntax is:

   case constant:

constant est la valeur à tester.where constant is the value to test for. constant peut être l’une quelconque des expressions constantes suivantes :constant can be any of the following constant expressions:

  • Un littéral de valeur booléenne, true ou falseA bool literal, either true or false.
  • Toute constante intégrale, de type int, long ou byteAny integral constant, such as an int, a long, or a byte.
  • Le nom d’une variable const déclaréeThe name of a declared const variable.
  • Une constante d’énumérationAn enumeration constant.
  • Un littéral de type charA char literal.
  • Un littéral de type stringA string literal.

L’expression constante est évaluée de la manière suivante :The constant expression is evaluated as follows:

  • Si expr et constant sont des types intégraux, l’opérateur d’égalité C# détermine si l’expression retourne true (autrement dit, si expr == constant).If expr and constant are integral types, the C# equality operator determines whether the expression returns true (that is, whether expr == constant).

  • Sinon, la valeur de l’expression est déterminée par un appel à la méthode statique Object.Equals(expr, constant).Otherwise, the value of the expression is determined by a call to the static Object.Equals(expr, constant) method.

L’exemple suivant utilise le modèle de constante pour déterminer si une date particulière correspond à un jour de week-end, au premier jour de la semaine, au dernier jour de la semaine de travail ou au milieu de la semaine de travail.The following example uses the constant pattern to determine whether a particular date is a weekend, the first day of the work week, the last day of the work week, or the middle of the work week. Il évalue la propriété DateTime.DayOfWeek du jour actuel par rapport aux membres de l’énumération DayOfWeek.It evaluates the DateTime.DayOfWeek property of the current day against the members of the DayOfWeek enumeration.

using System;

class Program
{
    static void Main()
    {
        switch (DateTime.Now.DayOfWeek)
        {
           case DayOfWeek.Sunday:
           case DayOfWeek.Saturday:
              Console.WriteLine("The weekend");
              break;
           case DayOfWeek.Monday:
              Console.WriteLine("The first day of the work week.");
              break;
           case DayOfWeek.Friday:
              Console.WriteLine("The last day of the work week.");
              break;
           default:
              Console.WriteLine("The middle of the work week.");
              break;   
        }
    }
}
// The example displays output like the following:
//       The middle of the work week.

L’exemple suivant utilise le modèle de constante pour gérer l’entrée d’utilisateur dans une application console qui simule une machine à café automatique.The following example uses the constant pattern to handle user input in a console application that simulates an automatic coffee machine.

using System;

class Example
{
   static void Main()
   {
       Console.WriteLine("Coffee sizes: 1=small 2=medium 3=large");
       Console.Write("Please enter your selection: ");
       string str = Console.ReadLine();
       int cost = 0;

       // Because of the goto statements in cases 2 and 3, the base cost of 25
       // cents is added to the additional cost for the medium and large sizes.
       switch (str)
       {
          case "1":
          case "small":
              cost += 25;
              break;
          case "2":
          case "medium":
              cost += 25;
              goto case "1";
          case "3":
          case "large":
              cost += 50;
              goto case "1";
          default:
              Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");
              break;
      }
      if (cost != 0)
      {
          Console.WriteLine("Please insert {0} cents.", cost);
      }
      Console.WriteLine("Thank you for your business.");
   }
}
// The example displays output like the following:
//         Coffee sizes: 1=small 2=medium 3=large
//         Please enter your selection: 2
//         Please insert 50 cents.
//         Thank you for your business.


Modèle de typeType pattern

Le modèle de type permet une évaluation et une conversion rapides de type.The type pattern enables concise type evaluation and conversion. Lorsqu’il est utilisé avec l’instruction switch pour effectuer une mise en correspondance de modèle, il permet de tester si une expression peut être convertie en un type spécifié et, si tel est le cas, il effectue un cast de l’expression en une variable de ce type.When used with the switch statement to perform pattern matching, it tests whether an expression can be converted to a specified type and, if it can be, casts it to a variable of that type. Sa syntaxe est la suivante :Its syntax is:

   case type varname 

type est le nom du type vers lequel le résultat de expr doit être converti, et varname est l’objet vers lequel le résultat de expr est converti si la correspondance est établie.where type is the name of the type to which the result of expr is to be converted, and varname is the object to which the result of expr is converted if the match succeeds.

L’expression case est true si l’une quelconque des affirmations suivantes est vraie :The case expression is true if any of the following is true:

  • expr est une instance du même type que type.expr is an instance of the same type as type.

  • expr est une instance d’un type qui dérive de type.expr is an instance of a type that derives from type. En d’autres termes, le résultat de expr peut être upcasté en une instance de type.In other words, the result of expr can be upcast to an instance of type.

  • expr a un type au moment de la compilation qui est une classe de base de type et expr a un type au moment de l’exécution égal à type ou dérivé de type.expr has a compile-time type that is a base class of type, and expr has a runtime type that is type or is derived from type. Le type au moment de la compilation d’une variable est le type de la variable, tel qu’il est défini dans sa déclaration de type.The compile-time type of a variable is the variable's type as defined in its type declaration. Le type au moment de l’exécution d’une variable est le type de l’instance qui est assignée à cette variable.The runtime type of a variable is the type of the instance that is assigned to that variable.

  • expr est une instance d’un type qui implémente l’interface type.expr is an instance of a type that implements the type interface.

Si l’expression case est true, varname est définitivement assigné et a une portée locale au sein de la section de commutation uniquement.If the case expression is true, varname is definitely assigned and has local scope within the switch section only.

Notez que null ne correspond pas à un type.Note that null does not match a type. Pour mettre en correspondance null, vous utilisez l’étiquette case suivante :To match a null, you use the following case label:

case null:

L’exemple suivant utilise le modèle de type pour fournir des informations sur différentes sortes de types de collection.The following example uses the type pattern to provide information about various kinds of collection types.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Example
{
    static void Main(string[] args)
    {
        int[] values = { 2, 4, 6, 8, 10 };
        ShowCollectionInformation(values);
        
        var names = new List<string>();
        names.AddRange( new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" } );
        ShowCollectionInformation(names);

        List<int> numbers = null;
        ShowCollectionInformation(numbers);
    }
   
    private static void ShowCollectionInformation(object coll)
    {
        switch (coll)
        {
            case Array arr:
               Console.WriteLine($"An array with {arr.Length} elements.");
               break;
            case IEnumerable<int> ieInt:
               Console.WriteLine($"Average: {ieInt.Average(s => s)}");
               break;   
            case IList list:
               Console.WriteLine($"{list.Count} items");
               break;
            case IEnumerable ie:
               string result = "";
               foreach (var item in ie) 
                  result += "${e} ";
               Console.WriteLine(result);
               break;   
            case null:
               // Do nothing for a null.
               break;
            default:
               Console.WriteLine($"A instance of type {coll.GetType().Name}");
               break;   
        }
    }
}
// The example displays the following output:
//     An array with 5 elements.
//     4 items

Sans critères spéciaux, ce code peut être écrit comme suit.Without pattern matching, this code might be written as follows. L’utilisation de critères spéciaux de type génère un code plus compact et lisible en éliminant la nécessité de tester si le résultat d’une conversion est un null et d’effectuer des casts répétés.The use of type pattern matching produces more compact, readable code by eliminating the need to test whether the result of a conversion is a null or to perform repeated casts.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Example
{
    static void Main(string[] args)
    {
        int[] values = { 2, 4, 6, 8, 10 };
        ShowCollectionInformation(values);
        
        var names = new List<string>();
        names.AddRange( new string[] { "Adam", "Abigail", "Bertrand", "Bridgette" } );
        ShowCollectionInformation(names);
        
        List<int> numbers = null;
        ShowCollectionInformation(numbers);
    }
   
    private static void ShowCollectionInformation(object coll)
    {
        if (coll is Array) {
           Array arr = (Array) coll;
           Console.WriteLine($"An array with {arr.Length} elements.");
        }
        else if (coll is IEnumerable<int>) {
            IEnumerable<int> ieInt = (IEnumerable<int>) coll;
            Console.WriteLine($"Average: {ieInt.Average(s => s)}");
        }
        else if (coll is IList) {
            IList list = (IList) coll;
            Console.WriteLine($"{list.Count} items");
        }
        else if (coll is IEnumerable) { 
            IEnumerable ie = (IEnumerable) coll;
            string result = "";
            foreach (var item in ie) 
               result += "${e} ";
            Console.WriteLine(result);
        }
        else if (coll == null) { 
            // Do nothing. 
        }
        else {
            Console.WriteLine($"An instance of type {coll.GetType().Name}");
        }   
    }
}
// The example displays the following output:
//     An array with 5 elements.
//     4 items

Instruction case et clause whenThe case statement and the when clause

À compter de C# 7.0, comme les instructions case ne s’excluent pas nécessairement mutuellement, vous pouvez ajouter une clause when pour spécifier une condition supplémentaire qui doit être satisfaite pour que l’instruction case soit évaluée à true.Starting with C# 7.0, because case statements need not be mutually exclusive, you can use add a when clause to specify an additional condition that must be satisfied for the case statement to evaluate to true. La clause when peut être toute expression qui retourne une valeur booléenne.The when clause can be any expression that returns a Boolean value. Le plus souvent, la clause when est utilisée pour empêcher l’exécution d’une section de commutation quand la valeur d’une expression de correspondance est null.One of the more common uses for the when clause is used to prevent a switch section from executing when the value of a match expression is null.

L’exemple suivant définit une classe Shape de base, une classe Rectangle qui dérive de Shape et une classe Square qui dérive de Rectangle.The following example defines a base Shape class, a Rectangle class that derives from Shape, and a Square class that derives from Rectangle. Il utilise la clause when pour garantir que le ShowShapeInfo traite un objet Rectangle qui s’est vu assigner des longueurs et des largeurs égales comme celles d’un objet Square même s’il n’a pas été instancié comme objet Square.It uses the when clause to ensure that the ShowShapeInfo treats a Rectangle object that has been assigned equal lengths and widths as a Square even if is has not been instantiated as a Square object. La méthode ne tente pas d’afficher des informations sur un objet null ou sur une forme dont l’aire est nulle.The method does not attempt to display information either about an object that is null or a shape whose area is zero.

using System;

public abstract class Shape
{
   public abstract double Area { get; }
   public abstract double Circumference { get; } 
}

public class Rectangle : Shape
{
   public Rectangle(double length, double width) 
   {
      Length = length;
      Width = width; 
   }

   public double Length { get; set; }
   public double Width { get; set; }
   
   public override double Area
   { 
      get { return Math.Round(Length * Width,2); } 
   } 
   
   public override double Circumference 
   {
      get { return (Length + Width) * 2; }
   }
}

public class Square : Rectangle
{
   public Square(double side) : base(side, side) 
   {
      Side = side; 
   }

   public double Side { get; set; }
}

public class Circle : Shape
{
   public Circle(double radius) 
   {
      Radius = radius;
   } 
   
   public double Radius { get; set; }

   public override double Circumference
   {
      get { return 2 * Math.PI * Radius; }
   }

   public override double Area
   {
      get { return Math.PI * Math.Pow(Radius, 2); } 
   }
}

public class Example
{
   public static void Main()
   {
      Shape sh = null;
      Shape[] shapes = { new Square(10), new Rectangle(5, 7),
                         sh, new Square(0), new Rectangle(8, 8),
                         new Circle(3) };
      foreach (var shape in shapes)
         ShowShapeInfo(shape);
   }

   private static void ShowShapeInfo(Shape sh)
   {
      switch (sh)
      {
         // Note that this code never evaluates to true.
         case Shape shape when shape == null:
            Console.WriteLine($"An uninitialized shape (shape == null)");
            break;
         case null:
            Console.WriteLine($"An uninitialized shape");
            break;
         case Shape shape when sh.Area == 0:
            Console.WriteLine($"The shape: {sh.GetType().Name} with no dimensions");
            break;
         case Square sq when sh.Area > 0:
            Console.WriteLine("Information about square:");
            Console.WriteLine($"   Length of a side: {sq.Side}");
            Console.WriteLine($"   Area: {sq.Area}");
            break;
         case Rectangle r when r.Length == r.Width && r.Area > 0:
            Console.WriteLine("Information about square rectangle:");
            Console.WriteLine($"   Length of a side: {r.Length}");
            Console.WriteLine($"   Area: {r.Area}");
            break;
         case Rectangle r when sh.Area > 0:
            Console.WriteLine("Information about rectangle:");
            Console.WriteLine($"   Dimensions: {r.Length} x {r.Width}");
            Console.WriteLine($"   Area: {r.Area}");
            break;
         case Shape shape when sh != null:
            Console.WriteLine($"A {sh.GetType().Name} shape");
            break;
         default:
            Console.WriteLine($"The {nameof(sh)} variable does not represent a Shape.");
            break;   
      }
   }
}
// The example displays the following output:
//       Information about square:
//          Length of a side: 10
//          Area: 100
//       Information about rectangle:
//          Dimensions: 5 x 7
//          Area: 35
//       An uninitialized shape
//       The shape: Square with no dimensions
//       Information about square rectangle:
//          Length of a side: 8
//          Area: 64
//       A Circle shape

Notez que la clause when dans l’exemple qui tente de tester si un objet Shape est null ne s’exécute pas.Note that the when clause in the example that attempts to test whether a Shape object is null does not execute. Le modèle de type correct à utiliser pour tester un null est case null:.The correct type pattern to test for a null is case null:.

Spécification du langage C#C# Language Specification

Pour plus d'informations, voir la spécification du langage C#.For more information, see the C# Language Specification. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.The language specification is the definitive source for C# syntax and usage.

Voir aussiSee Also

Référence C#C# Reference
Guide de programmation C#C# Programming Guide
Mots clés C#C# Keywords
if-elseif-else
Critères spéciauxPattern Matching