switch expression - 使用關鍵字的 switch 模式匹配表達式

使用該 switch 表達式從候選表達式列表中評估單一表達式。 評估基於與輸入表達式的模式匹配。 如需語句內容中支持switch類似語意的語句資訊switch,請參閱 switchSelection 語句一文的 語句一節。

C# 語言參考資料記錄了 C# 語言最新版本。 同時也包含即將推出語言版本公開預覽功能的初步文件。

文件中標示了語言最近三個版本或目前公開預覽版中首次引入的任何功能。

小提示

欲查詢某功能何時首次在 C# 中引入,請參閱 C# 語言版本歷史的條目。

以下範例展示了一個 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 運算式arm都包含 模式、選擇性 大小寫防護、 => 令牌和 表達式。

在前述範例中,表達 switch 式使用以下模式:

  • 常數模式:處理列舉定義的Direction值。
  • 捨棄模式:處理任何沒有列舉之對應成員的Direction整數值(例如 , (Direction)10。 這種模式讓這個 switch 表達變得 詳盡無遺。

這很重要

如需表達式所支援的 switch 模式和更多範例的相關信息,請參閱 模式。

運算式的結果是第一switch個switch表達式arm的運算式值,其模式符合輸入運算式,如果存在,則其案例防護會評估為 true。 表達式 switch 臂會以文字順序進行評估。

當無法選擇較低的 switch 表達式arm時,編譯程式會產生錯誤,因為較高的 switch 表達式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框架中,例外是 InvalidOperationException。 在大部分情況下,如果 switch 表達式未處理所有可能的輸入值,編譯程式會產生警告。 未處理所有可能輸入時,清單模式不會產生警告。

對於 聯合型別,當一個 switch 表達式處理所有案件類型時,即為窮全。 不需要萬能的手臂。 如果 union Value 屬性的 null 狀態是「可能是 null」,你也必須處理 null 以避免收到警告。 欲了解更多資訊,請參閱 聯邦的全面性。

預設產生的聯集即使所有案例類型皆不可空,仍可包含 null ,例如新分配的聯集陣列元素或由 創建 default的值。 編譯器不一定會在那種情況下警告 null 缺少手臂,但如果沒有手臂匹配,開關還是會跳掉。 處理 null 預設聯合內容何時能到達交換器。 建議選擇 arm null 而非 var a 或 discard,這樣新增案件類型仍會產生非窮盡性警告。

小提示

若要保證 switch 表達式會處理所有可能的輸入值,請提供 switch 具有 捨棄模式的運算式臂。

C# 語言規格

如需詳細資訊,請參閱 switchC# 語言規格的運算式區段。

另請參閱