switch 表达式 - 使用关键字的
使用 switch
表达式根据模式匹配与输入表达式计算候选表达式列表中的单个表达式。 有关语句上下文中支持switch
类似语义的语句的信息switch
,请参阅 switch
Selection 语句文章的语句部分。
以下示例演示一个 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
表达式使用以下模式:
重要
有关表达式支持的 switch
模式和更多示例的信息,请参阅 Patterns。
表达式的结果是第一switch
个switch
表达式 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),
};
非详尽的开关表达式
如果表达式的模式都与 switch
输入值匹配,运行时将引发异常。 在 .NET Core 3.0 及更高版本中,例外是一种 System.Runtime.CompilerServices.SwitchExpressionException。 在 .NET Framework 中,异常是一个 InvalidOperationException。 在大多数情况下,如果 switch
表达式未处理所有可能的输入值,编译器将生成警告。 如果未处理所有可能的输入,则列表模式不会生成警告。
小窍门
若要保证switch
表达式处理所有可能的输入值,请提供具有switch
放弃模式的表达式臂。