首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# switch 語句進階秘籍:Fallthrough、Goto、變量作用域與編譯器窮盡性檢查

     編輯:關於C語言

前言

C# 的 switch 看似簡單,實則暗藏嚴格規則與強大模式匹配能力。本文揭示四大「你可能不知道」的特性,助你寫出更安全、更優雅的分支代碼。

一、禁止隱式 Fallthrough —— 必須顯式 break 或 goto

int i = 0;
switch (i) {
    case 0:
        Console.WriteLine("0");
        // 編譯錯誤 CS0163: Control cannot fall through from one case label to another
    case 1:
        Console.WriteLine("1");
        break;
}

規則:C# 要求每個 case 塊必須以 break、return、throw 或 goto 結束,**禁止隱式貫穿**。這消除了 C/C++ 中漏寫 break 導致的經典 Bug。

合法的 Fallthrough 方式:goto case

switch (i) {
    case 0:
        Console.WriteLine("0");
        goto case 1; // 顯式跳轉,合法
    case 1:
        Console.WriteLine("1");
        break;
}

case 標簽在 C# 中本質是標號,goto case 常量 / goto default 提供了受控的貫穿能力。

二、default 也不例外:不可隱式貫穿

switch (i) {
    case 0: DoSomething(); break;
    default:
        // 若此處無 break/return/goto,且非最後一個 case,仍報錯
        LogDefault();
        // 錯誤:Control cannot fall through...
}

即使 default 邏輯為空,也需顯式 break 或置於最後。

三、Case 標簽作用域陷阱:變量聲明需加大括號

switch (i) {
    case 0:
        int y = 10; // 錯誤 CS0028: A local variable named 'y' cannot be declared in this scope
        break;
    case 1:
        int y = 20; // 與 case 0 同層作用域,衝突!
        break;
}

原因:switch 整體僅形成**單一聲明空間**,case 不創建新作用域。

解決方案 1:塊語句隔離 (推薦)

case 0: {
    int y = 10; // OK
    break;
}
case 1: {
    int y = 20; // OK
    break;
}

解決方案 2:聲明前置 (不推薦,擴大作用域)

int y;
switch (i) {
    case 0: y = 10; break;
    case 1: y = 20; break;
}

四、編譯器窮盡性檢查:bool 也不夠聰明

int M(bool b) {
    switch (b) {
        case true:  return 1;
        case false: return 0;
        // 編譯錯誤 CS0161: 'M': not all code paths return a value
    }
}

原理:編譯器不分析 bool 只有兩值的語義,僅按控制流圖判斷:switch 可能不進入任何 case (如未來擴展類型)、或 case 體內不返回。因此要求**所有路徑**顯式返回。

修復方案

// 方案 1:default 兜底 (語義等價)
int M(bool b) {
    switch (b) {
        case true: return 1;
        default:   return 0; // 編譯器認可所有路徑覆蓋
    }
}

// 方案 2:三元運算符 (更簡潔)
int M(bool b) => b ? 1 : 0;

五、現代 C# 擴展:模式匹配 (C# 7+) 與 Switch 表達式 (C# 8+)


// 屬性模式 + Switch 表達式 (C# 8)
string Describe(object o) => o switch {
    int i when i > 0 => "正整數",
    int i => "非正整數",
    string s when s.Length > 10 => "長字符串",
    null => "空引用",
    _ => "其他類型"
};

表達式體自動保證窮盡性,無需 break,代碼更函數式、更安全。

總結

特性C/C++C# (傳統)C# 8+ 表達式
隱式 Fallthrough允許 (危險)禁止 (編譯錯誤)不存在
顯式 Fallthrough無需關鍵字goto case多模式逗號分隔
Case 作用域同 Switch同 Switch (需 { } 隔離)獨立
窮盡性檢查無控制流分析模式匹配強制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved