Switch (odwołanie w C#)switch (C# reference)

switch jest instrukcją zaznaczenia, który wybiera jeden Przełącz sekcję do wykonania z listy kandydatów na podstawie dopasowania wzorca z pasuje do wyrażenia.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

switch Instrukcji jest często używana jako alternatywa if-else konstruowania, jeśli pojedyncze wyrażenie jest testowany dla trzech lub więcej warunków.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. Na przykład następująca switch Instrukcja określa, czy zmienna typu Color ma jedną z trzech wartości: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;   
      }
   }
}

Jest to równoważne do poniższego przykładu, który używa if - else konstruowania.It's 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

Wyrażenie dopasowaniaThe match expression

Wyrażenie dopasowania udostępnia wartość do dopasowywania wzorców w case etykiety.The match expression provides the value to match against the patterns in case labels. Jego składnia jest następująca:Its syntax is:

   switch (expr)

W C# 6 i starszych wersjach, wyrażenie dopasowania musi być wyrażeniem, która zwraca wartość z następujących typów:In C# 6 and earlier, the match expression must be an expression that returns a value of the following types:

Wyrażenie dopasowania, począwszy od języka C# 7.0, może być dowolnym wyrażeniem inną niż null.Starting with C# 7.0, the match expression can be any non-null expression.

Sekcja przełącznikaThe switch section

A switch wyciąg zawiera jeden lub więcej sekcji przełączników.A switch statement includes one or more switch sections. Każda sekcja przełącznika zawiera jedną lub więcej zamierzone, Zapisz etykiety (etykieta case lub default) następuje jedna lub więcej instrukcji.Each switch section contains one or more case labels (either a case or default label) followed by one or more statements. switch Instrukcja może zawierać co najwyżej jedną etykietę domyślną umieszczone w żadnej sekcji przełącznika.The switch statement may include at most one default label placed in any switch section. W poniższym przykładzie przedstawiono prosty switch instrukcję, która zawiera trzy sekcje przełącznika, każdy z nich zawierający dwie instrukcje.The following example shows a simple switch statement that has three switch sections, each containing two statements. Druga sekcja przełącznika zawiera case 2: i case 3: etykiety.The second switch section contains the case 2: and case 3: labels.

A switch instrukcji może zawierać dowolną liczbę sekcji przełącznika, a każda sekcja może mieć jedną lub więcej etykiet wielkości liter, jak pokazano w poniższym przykładzie.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. Jednak żadne dwie etykiety mogą zawierać to samo wyrażenie.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

Wykonuje sekcji tylko jednego przełącznika w instrukcji switch.Only one switch section in a switch statement executes. C#Nie zezwalaj na wykonywanie kontynuowało z jednej sekcji przełączania do następnej.C# doesn't allow execution to continue from one switch section to the next. W związku z tym poniższy kod generuje błąd kompilatora CS0163: "Sterowanie nie może przechodzić od jednej etykiety case (<etykietę" case ">) do innego."Because of this, the following code generates a compiler error, CS0163: "Control cannot fall through from one case label (<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;
}

Wymóg ten jest zazwyczaj spełniony przy jawnie zamykania sekcji przełącznika, za pomocą podziału, goto, lub zwracają instrukcji.This requirement is usually met by explicitly exiting the switch section by using a break, goto, or return statement. Jednak poniższy kod jest również ważne, ponieważ zapewnia, że formant programu nie może przechodzić do default Przełącz sekcję.However, the following code is also valid, because it ensures that program control can't 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;                 
}  

Wykonanie listy instrukcji w sekcji przełącznika, etykietę case, która odpowiada wyrażeniu dopasowanie rozpoczyna się od pierwszej instrukcji i przechodzi przez listę instrukcji, zwykle aż do instrukcja skoku, takiej jak break, goto case, goto label, return, lub throw, zostanie osiągnięty.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. W tym momencie przekazanie kontroli poza switch instrukcji lub do innej etykiety sprawy.At that point, control is transferred outside the switch statement or to another case label. A goto instrukcji, jeśli jest on używany, musi kontrola jest przekazywana do stałej etykiety.A goto statement, if it's used, must transfer control to a constant label. To ograniczenie jest konieczne, ponieważ próby kontrola jest przekazywana do etykiety niestałe może mieć niepożądane skutki uboczne, takie transferowanie formantu do niezamierzonych lokalizacji w kodzie lub tworzenie pętli nieskończonej.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.

Etykiety CaseCase labels

Każda etykieta przypadku określa wzorzec do porównania z wyrażenia dopasowania ( caseSwitch zmiennej w poprzednich przykładach).Each case label specifies a pattern to compare to the match expression (the caseSwitch variable in the previous examples). Jeśli są zgodne, kontrola jest przekazywana do sekcji przełącznika, który zawiera pierwszy odpowiadających im etykiet wielkości liter.If they match, control is transferred to the switch section that contains the first matching case label. Jeśli nie wzorzec etykietę "case" pasuje do wyrażenia dopasowania, kontrola jest przekazywana do sekcji z default etykiety case, jeśli taka istnieje.If no case label pattern matches the match expression, control is transferred to the section with the default case label, if there's one. W przypadku nie default przypadku żadnych deklaracji w żadnej sekcji przełącznika są wykonywane, a kontrola jest przekazywana poza switch instrukcji.If there's no default case, no statements in any switch section are executed, and control is transferred outside the switch statement.

Instrukcje dotyczące switch instrukcji i dopasowywania do wzorca, zobacz dopasowywania do wzorca z switch instrukcji sekcji.For information on the switch statement and pattern matching, see the Pattern matching with the switch statement section.

Ponieważ C# 6 obsługuje tylko stałe wzorzec i nie zezwala na powtórzenia wartości stałych, etykiet case zdefiniować wartości wzajemnie się wykluczają i tylko jeden wzorzec może być zgodna z wyrażeniem dopasowania.Because C# 6 supports only the constant pattern and doesn't allow the repetition of constant values, case labels define mutually exclusive values, and only one pattern can match the match expression. W rezultacie, kolejność, w której case instrukcje są wyświetlane, nie ma znaczenia.As a result, the order in which case statements appear is unimportant.

W języku C# 7.0, ponieważ inne wzorce są obsługiwane, etykiet case nie muszą definiować wartości wzajemnie się wykluczają i wielu wzorców może odnosić się wyrażenie dopasowania.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. Ponieważ wykonywane są tylko instrukcje w pierwszej sekcji przełącznika, który zawiera pasującego wzorca, kolejność, w której case instrukcje pojawiają się teraz jest ważne.Because only the statements in the first switch section that contains the matching pattern are executed, the order in which case statements appear is now important. Jeśli C# wykryje sekcji przełącznika, których instrukcji case instrukcje są równoważne lub są podzbiorem poprzednich instrukcji, generuje błąd kompilatora, CS8120, "przypadku switch została już obsłużona przez poprzednią etykietę case."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."

W poniższym przykładzie pokazano switch instrukcję, która korzysta z rozmaitych wzorców bez wzajemnie się wykluczają.The following example illustrates a switch statement that uses a variety of non-mutually exclusive patterns. Jeśli przeniesiesz case 0: Przełącz sekcję, tak aby nie jest już pierwszą sekcją switch instrukcji C# generuje błąd kompilatora, ponieważ liczbą całkowitą, którego wartość jest równa zero jest podzbiorem wszystkich liczb całkowitych, która jest wzorzec zdefiniowany przez case int val instrukcji.If you move the case 0: switch section so that it's 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>();
   }
}

Można rozwiązać ten problem i wyeliminować ostrzeżenia kompilatora, w jeden z dwóch sposobów:You can correct this issue and eliminate the compiler warning in one of two ways:

  • Zmieniając ich kolejność sekcji przełączników.By changing the order of the switch sections.

  • Za pomocą po klauzuli w case etykiety.By using a when clause in the case label.

default CaseThe default case

default Case określa sekcji przełącznika, do wykonania, jeśli wyrażenie dopasowania nie odpowiada żadnej innej case etykiety.The default case specifies the switch section to execute if the match expression doesn't match any other case label. Jeśli default przypadek nie jest obecny i wyrażenie dopasowania nie odpowiada żadnej innej case etykiety, przepływem programu przypada za pośrednictwem switch instrukcji.If a default case is not present and the match expression doesn't match any other case label, program flow falls through the switch statement.

default Przypadków mogą być wyświetlane w dowolnej kolejności w switch instrukcji.The default case can appear in any order in the switch statement. Niezależnie od ich kolejność, w kodzie źródłowym, będzie zawsze oceniana, last, po wszystkich case etykiety zostały ocenione.Regardless of its order in the source code, it's always evaluated last, after all case labels have been evaluated.

Za pomocą dopasowywania do wzorca switch — instrukcja Pattern matching with the switch statement

Każdy case instrukcja definiuje wzorzec pasujący wyrażenie dopasowania powoduje, że jego zawierającego sekcji przełącznika, do wykonania.Each case statement defines a pattern that, if it matches the match expression, causes its containing switch section to be executed. Wszystkie wersje języka C# obsługuje wzór stałej.All versions of C# support the constant pattern. Pozostałe wzorce są obsługiwane, począwszy od języka C# 7.0.The remaining patterns are supported beginning with C# 7.0.

Wzór stałejConstant pattern

Wzór stałej sprawdza, czy wyrażenie dopasowania jest równa określonej stałej.The constant pattern tests whether the match expression equals a specified constant. Jego składnia jest następująca:Its syntax is:

   case constant:

gdzie stałej jest wartością do testowania.where constant is the value to test for. Stała może być dowolną z następujących stałych wyrażeń:constant can be any of the following constant expressions:

  • A bool literału, albo true lub false.A bool literal, either true or false.
  • Dowolnego całkowitego stałych, takich jak int, długie, lub bajt.Any integral constant, such as an int, a long, or a byte.
  • Nazwa deklarowanej const zmiennej.The name of a declared const variable.
  • Stała wyliczenia.An enumeration constant.
  • A char literału.A char literal.
  • A ciąg literału.A string literal.

Stałe wyrażenie jest obliczane w następujący sposób:The constant expression is evaluated as follows:

  • Jeśli expr i stałej typów całkowitych operatora porównania języka C# Określa, czy wyrażenie zwraca true (oznacza to, czy expr == constant).If expr and constant are integral types, the C# equality operator determines whether the expression returns true (that is, whether expr == constant).

  • W przeciwnym razie wartość wyrażenia jest określana przez wywołanie statycznego metody Object.Equals (wyrażenie stałe) metody.Otherwise, the value of the expression is determined by a call to the static Object.Equals(expr, constant) method.

W poniższym przykładzie użyto wzór stałej, aby ustalić, czy określoną datę w weekendy, pierwszego dnia tygodnia pracy, ostatni dzień tygodnia pracy lub w środku tygodnia pracy.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. Powoduje ono obliczenie DateTime.DayOfWeek właściwości bieżącego dnia w odniesieniu do składowych aspektów DayOfWeek wyliczenia.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.

W poniższym przykładzie użyto wzór stałej do obsługi danych wejściowych użytkownika w aplikacji konsoli, która symuluje maszyny do automatycznego kawy.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.


Wpisz wzórType pattern

Wpisz wzór umożliwia ocenę zwięzły typ i konwersji.The type pattern enables concise type evaluation and conversion. Gdy jest używane z switch instrukcję do realizacji dopasowania do wzorca, jego testuje, czy wyrażenie można przekonwertować na określony typ i, jeśli może zostać rzutuje zmiennej tego typu.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. Jego składnia jest następująca:Its syntax is:

   case type varname

gdzie typu jest nazwą typu, do której wynik expr ma być przekonwertowany i nazwa_zmiennej obiekt, do którego jest wynikiem exprjest konwertowany, jeśli dopasowanie się powiedzie.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. Typ kompilacji expr może być parametrem typu ogólnego, począwszy od C# 7.1.The compile-time type of expr may be a generic type parameter, starting with C# 7.1.

case Wyrażenie jest true jeśli spełniony jest dowolny z następujących czynności:The case expression is true if any of the following is true:

  • wyrażenie to wystąpienie tego samego typu co typu.expr is an instance of the same type as type.

  • wyrażenie jest wystąpieniem typu, który pochodzi od klasy typu.expr is an instance of a type that derives from type. Innymi słowy, wynikiem expr może być rzutowany w górę do wystąpienia typu.In other words, the result of expr can be upcast to an instance of type.

  • wyrażenie ma typ kompilacji, która jest klasą bazową dla typu, i expr ma typ środowiska uruchomieniowego, który jest typu lub typu pochodnego względem typu.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. Typów w czasie kompilacji zmiennej jest typem zmiennej, zgodnie z definicją w jego deklaracji typu.The compile-time type of a variable is the variable's type as defined in its type declaration. Typ środowiska uruchomieniowego zmiennej jest typem wystąpienia, która jest przypisana do zmiennej.The runtime type of a variable is the type of the instance that is assigned to that variable.

  • wyrażenie jest wystąpieniem typu, który implementuje typu interfejsu.expr is an instance of a type that implements the type interface.

Jeśli wyrażenie case ma wartość true, nazwa_zmiennej jest zdecydowanie przypisana, a ma zakres lokalny w ramach tej sekcji przełącznika.If the case expression is true, varname is definitely assigned and has local scope within the switch section only.

Należy pamiętać, że null nie jest zgodny z typem.Note that null doesn't match a type. Aby dopasować null, użyj następującego case etykiety:To match a null, you use the following case label:

case null:

W poniższym przykładzie użyto wzorca typu, aby podać informacje o różnych rodzajów typów kolekcji.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 e 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

Zamiast object, można utworzyć metody ogólnej przy użyciu typu kolekcji jako parametr typu, jak pokazano w poniższym kodzie:Instead of object, you could make a generic method, using the type of the collection as the type parameter, as shown in the following code:

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<T>(T 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 e in ie) 
                  result += "${e} ";
               Console.WriteLine(result);
               break;   
            case object o:
               Console.WriteLine($"A instance of type {o.GetType().Name}");
               break;   
            default:
                Console.WriteLine("Null passed to this method.");
                break;
        }
    }
}
// The example displays the following output:
//     An array with 5 elements.
//     4 items
//     Null passed to this method.

Ogólny wersja jest inna niż pierwszy przykład na dwa sposoby.The generic version is different than the first sample in two ways. Po pierwsze, nie można użyć null przypadek.First, you can't use the null case. Nie można używać każdy przypadek, stałe, ponieważ kompilator nie może przekonwertować dowolny typ dowolnego T do dowolnego typu innego niż object.You can't use any constant case because the compiler can't convert any arbitrary type T to any type other than object. Był default zamierzone, Zapisz teraz testy dla innych niż null object.What had been the default case now tests for a non-null object. Oznacza to, że default zamierzone, Zapisz testy tylko w przypadku null.That means the default case tests only for null.

Bez dopasowywania do wzorca, ten kod może być zapisana w następujący sposób.Without pattern matching, this code might be written as follows. Używanie dopasowania wzorca typu generuje kod bardziej zwarty, czytelny dzięki wyeliminowaniu konieczności, aby sprawdzić, czy wynik konwersji jest null lub do wykonywania powtarzających rzutowania.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 e 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

case Instrukcji i when — klauzula The case statement and the when clause

Uruchamianie przy użyciu języka C# 7.0, ponieważ instrukcji case nie muszą być wzajemnie się wykluczają, możesz dodać when klauzulę, aby określić dodatkowy warunek muszą być spełnione dla instrukcji case na wartość true.Starting with C# 7.0, because case statements need not be mutually exclusive, you can add a when clause to specify an additional condition that must be satisfied for the case statement to evaluate to true. when Klauzuli może być dowolne wyrażenie zwracające wartość logiczną.The when clause can be any expression that returns a Boolean value.

W poniższym przykładzie zdefiniowano podstawowej Shape klasy Rectangle klasę pochodzącą od Shape, a Square klasę pochodzącą od Rectangle.The following example defines a base Shape class, a Rectangle class that derives from Shape, and a Square class that derives from Rectangle. Używa ona when klauzuli, aby upewnić się, że ShowShapeInfo traktuje Rectangle obiekt, który został przypisany równy długości i szerokości jako Square nawet wtedy, gdy nie został uruchomiony jako Square obiektu.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 it hasn't been instantiated as a Square object. Metoda nie próbuje wyświetlać informacje o obiekt, który jest null lub kształtu, w których obszar jest równa zero.The method doesn't 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

Należy pamiętać, że when klauzuli w przykładzie, który próbuje testów czy Shape obiekt jest null nie jest wykonywany.Note that the when clause in the example that attempts to test whether a Shape object is null doesn't execute. Wzorzec poprawnego typu do testowania null jest case null:.The correct type pattern to test for a null is case null:.

specyfikacja języka C#C# language specification

Aby uzyskać więcej informacji, zobacz instrukcji switch w specyfikacji języka C#.For more information, see The switch statement in the C# Language Specification. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.The language specification is the definitive source for C# syntax and usage.

Zobacz takżeSee also