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

可以使用 switch 表达式,根据与输入表达式匹配的模式,对候选表达式列表中的单个表达式进行求值。 有关在语句上下文中支持 switch 类语义的 switch 语句的信息,请参阅选择语句一文的 switch 语句部分。

下面的示例演示了一个 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 expression arm,用逗号分隔。 每个 switch expression arm 都包含一个模式、一个可选的 case guard=> 标记和一个表达式 。

在上述示例中,switch 表达式使用以下模式:

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

重要

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

switch 表达式的结果是第一个 switch expression arm 的表达式的值,该 switch expression arm 的模式与范围表达式匹配,并且它的 case guard(如果存在)求值为 trueswitch expression arm 按文本顺序求值。

如果无法选择较低的 switch expression arm,编译器会发出错误,因为较高的 switch expression arm 匹配其所有值。

Case guard

模式或许表现力不够,无法指定用于计算 arm 的表达式的条件。 在这种情况下,可以使用 case guard。 case guard 是一个附加条件,必须与匹配模式同时满足。 case guard 必须是布尔表达式。 可以在模式后面的 when 关键字之后指定一个 case guard,如以下示例所示:

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 表达式

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

提示

为了保证 switch 表达式处理所有可能的输入值,请为 switch expression arm 提供弃元模式

C# 语言规范

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

另请参阅