Ausdruck „switch“: Musterabgleichsausdrücke unter Verwendung des Schlüsselworts switch

Sie verwenden den Ausdruck switch, um einen einzelnen Ausdruck in einer Liste mit möglichen Ausdrücken auf Grundlage eines Musterabgleichs mit einem Eingabeausdruck auszuwerten. Informationen zur switch-Anweisung, die switch-ähnliche Semantik in einem Anweisungskontext unterstützt, finden Sie im Artikel Auswahlanweisungen (C#-Referenz) im Abschnitt zur switch-Anweisung.

Das folgende Beispiel veranschaulicht einen switch-Ausdruck, der Werte eines enum-Typs, die für visuelle Richtungen auf einer Onlinekarte stehen, in die entsprechenden Kardinalrichtungen konvertiert:

public static class SwitchExample
{
    public enum Direction
    {
        Up,
        Down,
        Right,
        Left
    }

    public enum Orientation
    {
        North,
        South,
        East,
        West
    }

    public static Orientation ToOrientation(Direction direction) => direction switch
    {
        Direction.Up    => Orientation.North,
        Direction.Right => Orientation.East,
        Direction.Down  => Orientation.South,
        Direction.Left  => Orientation.West,
        _ => throw new ArgumentOutOfRangeException(nameof(direction), $"Not expected direction value: {direction}"),
    };

    public static void Main()
    {
        var direction = Direction.Right;
        Console.WriteLine($"Map view direction is {direction}");
        Console.WriteLine($"Cardinal orientation is {ToOrientation(direction)}");
        // Output:
        // Map view direction is Right
        // Cardinal orientation is East
    }
}

Das vorstehende Beispiel zeigt die grundlegenden Elemente eines switch-Ausdrucks:

  • Es handelt sich um einen vom Schlüsselwort switch gefolgten Ausdruck. Im vorherigen Beispiel ist das der Methodenparameter direction.
  • Hierbei handelt es sich um die durch Kommas getrennten Verzweigungsarme des switch-Ausdrucks. Jeder Verzweigungsarm des switch-Ausdrucks enthält ein Muster, einen optionalen Case Guard, das =>-Token und einen Ausdruck.

Im vorherigen Beispiel nutzt ein switch-Ausdruck die folgenden Muster:

  • Ein Konstantenmuster: Hiermit werden die definierten Werte der Direction-Enumeration verarbeitet.
  • Ein Ausschussmuster: Hiermit wird jeder ganzzahlige Wert verarbeitet, der nicht über den entsprechenden Member der Direction-Enumeration verfügt (z. B. (Direction)10). So liegt ein vollständigerswitch-Ausdruck vor.

Wichtig

Informationen zu den von einem switch-Ausdruck unterstützten Mustern und weitere Beispiele finden Sie unter Muster.

Das Ergebnis eines switch-Ausdrucks ist der Wert des Ausdrucks des ersten switch-Ausdruckverzweigungsarms, dessen Muster mit dem des Eingabeausdrucks übereinstimmt und bei dem der Case Guard (sofern vorhanden) als true ausgewertet wird. Die switch-Ausdruckverzweigungsarme werden in der Textreihenfolge ausgewertet.

Der Compiler gibt einen Fehler aus, wenn ein niedrigerer switch-Ausdruckverzweigungsarm nicht ausgewählt werden kann, weil ein höherer switch-Ausdruckverzweigungsarm allen Werten entspricht.

Case Guards

Ein Muster ist möglicherweise nicht ausdrucksstark genug, um die Bedingung für die Auswertung des Ausdrucks einer Verzweigung anzugeben. In so einem Fall können Sie einen Case Guard verwenden. Ein Case Guard ist eine weitere Bedingung, die zusammen mit einem übereinstimmenden Muster erfüllt werden muss. Ein Case Guard muss ein boolescher Ausdruck sein. Sie geben einen Case Guard nach dem when-Schlüsselwort an, das einem Muster folgt. Sehen Sie sich dazu das folgende Beispiel an:

public readonly struct Point
{
    public Point(int x, int y) => (X, Y) = (x, y);
    
    public int X { get; }
    public int Y { get; }
}

static Point Transform(Point point) => point switch
{
    { X: 0, Y: 0 }                    => new Point(0, 0),
    { X: var x, Y: var y } when x < y => new Point(x + y, y),
    { X: var x, Y: var y } when x > y => new Point(x - y, y),
    { X: var x, Y: var y }            => new Point(2 * x, 2 * y),
};

Im vorherigen Beispiel werden Eigenschaftenmuster mit geschachtelten var-Mustern verwendet.

Unvollständige switch-Ausdrücke

Wenn keines der Muster eines switch-Ausdrucks mit einem Eingabewert übereinstimmt, wird von der Runtime eine Ausnahme zurückgegeben. In .NET Core 3.0 und höher ist die Ausnahme eine System.Runtime.CompilerServices.SwitchExpressionException-Klasse. Im .NET Framework ist die Ausnahme eine InvalidOperationException-Klasse. In den meisten Fällen generiert der Compiler eine Warnung, wenn ein switch-Ausdruck nicht alle möglichen Eingabewerte verarbeiten kann. Listenmuster generieren keine Warnung, wenn nicht alle möglichen Eingaben verarbeitet werden.

Tipp

Wenn sichergestellt werden soll, dass ein switch-Ausdruck alle möglichen Eingabewerte verarbeitet, stellen Sie für einen Verzweigungsarm des switch-Ausdrucks ein Ausschussmuster bereit.

C#-Sprachspezifikation

Weitere Informationen erhalten Sie im Abschnitt zum switch-Ausdruck des Artikels Rekursiver Musterabgleich.

Siehe auch