switch 表达式 - 使用关键字的 switch 模式匹配表达式

使用 switch 表达式根据模式匹配与输入表达式计算候选表达式列表中的单个表达式。 有关语句上下文中支持switch类似语义的语句的信息switch,请参阅 switchSelection 语句文章的语句部分。

以下示例演示一个 switch 表达式,该表达式将联机地图中表示视觉方向的值 enum 转换为相应的基数方向:

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
    }
}

前面的示例显示了表达式的基本元素 switch

  • 后跟关键字的 switch 表达式。 在前面的示例中,它是 direction 方法参数。
  • 表达式switch,用逗号分隔。 每个 switch 表达式臂都包含一个 模式、一个可选 大小写防护=> 标记和 一个表达式

在前面的示例中, switch 表达式使用以下模式:

  • 常量模式:用于处理枚举的Direction已定义值。
  • 放弃模式:用于处理没有枚举的Direction相应成员的任何整数值(例如, (Direction)10)。 switch这使得表达式详尽无遗

重要

有关表达式支持的 switch 模式和更多示例的信息,请参阅 Patterns

表达式的结果是第一switchswitch表达式 arm 的表达式的值,其模式与输入表达式匹配,如果存在,则其事例防护的计算结果为 true。 表达式 switch 臂按文本顺序计算。

当无法选择较低 switch 表达式臂时,编译器将生成一个错误,因为较高的 switch 表达式 arm 匹配其所有值。

案例防护

模式可能不够表现力,无法指定 arm 表达式计算的条件。 在这种情况下,可以使用 事例防护案例防护是必须满足与匹配模式一起的另一个条件。 事例防护必须是布尔表达式。 在遵循模式的 when 关键字后面指定事例防护,如以下示例所示:

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),
};

前面的示例使用具有嵌套 var 模式的属性模式

非详尽的开关表达式

如果表达式的模式都与 switch 输入值匹配,运行时将引发异常。 在 .NET Core 3.0 及更高版本中,例外是一种 System.Runtime.CompilerServices.SwitchExpressionException。 在 .NET Framework 中,异常是一个 InvalidOperationException。 在大多数情况下,如果 switch 表达式未处理所有可能的输入值,编译器将生成警告。 如果未处理所有可能的输入,则列表模式不会生成警告。

小窍门

若要保证switch表达式处理所有可能的输入值,请提供具有switch放弃模式的表达式臂。

C# 语言规范

有关详细信息,请参阅switch功能建议说明的表达式部分。

另请参阅