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(如果存在)求值为 true
。 switch
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),
};
非详尽的 switch 表达式
如果 switch
表达式的模式均未捕获输入值,则运行时将引发异常。 在 .NET Core 3.0 及更高版本中,异常是 System.Runtime.CompilerServices.SwitchExpressionException。 在 .NET Framework 中,异常是 InvalidOperationException。 大大多数情况下,如果 switch
表达式未处理所有可能的输入值,则编译器会生成警告。 如果未处理所有可能的输入,列表模式不会生成警告。
提示
为了保证 switch
表达式处理所有可能的输入值,请为 switch
expression arm 提供弃元模式。
C# 语言规范
有关详细信息,请参阅功能建议说明的 switch
表达式部分。