判斷陳述式 控制程式流程依條件分支執行。C# 提供 if-else、switch、模式比對、三元運算子等多樣化工具。選擇正確結構能大幅提升可讀性、減少 Bug、啟用編譯器最佳化。
if-else 陳述式// 基本
if (score >= 60) {
Console.WriteLine("及格");
} else {
Console.WriteLine("不及格");
}
// 多重條件
if (score >= 90) grade = 'A';
else if (score >= 80) grade = 'B';
else if (score >= 70) grade = 'C';
else if (score >= 60) grade = 'D';
else grade = 'F';
// 巢狀
if (user != null) {
if (user.IsActive) {
if (user.HasPermission("admin")) { /* ... */ }
}
}
// 守衛子句:扁平化
if (user == null) return;
if (!user.IsActive) return;
if (!user.HasPermission("admin")) return;
// 核心邏輯...
switch 陳述式:傳統與新式switch (day) {
case 1: case 2: case 3: case 4: case 5:
Console.WriteLine("平日"); break;
case 6: case 7:
Console.WriteLine("週末"); break;
default:
Console.WriteLine("無效"); break;
}
// 字串 switch
switch (command.ToLower()) {
case "start": Start(); break;
case "stop": Stop(); break;
case "restart": Restart(); break;
default: Unknown(); break;
}
// 基本
string result = day switch {
1 or 2 or 3 or 4 or 5 => "平日",
6 or 7 => "週末",
_ => "無效"
};
// 型別模式
object Process(object input) => input switch {
int i => i * 2,
string s => s.Length,
double d when d > 0 => (int)d,
null => "空值",
_ => "未知"
};
// 屬性模式
var discount = customer switch {
{ IsVip: true, Years: >= 5 } => 0.25,
{ IsVip: true } => 0.15,
{ Years: >= 10 } => 0.10,
_ => 0.0
};
// Tuple 模式
(string, int) Parse(string input) => input.Split(',') switch {
[var name, var ageStr] when int.TryParse(ageStr, out var age) => (name, age),
_ => ("", 0)
};
// 列表/切片模式 (C# 11+)
int[] nums = {1,2,3};
string desc = nums switch {
[] => "空",
[var single] => $"單一: {single}",
[var first, .., var last] => $"首:{first} 尾:{last}",
_ => "其他"
};
| 特性 | switch 陳述式 | switch 運算式 |
|---|---|---|
| 語法 | switch (x) { case ... } | x switch { ... } |
| 結果 | 無 (執行敘述) | 有值 (可指派) |
| Fall-through | 需 break/goto case | 無 (模式互斥) |
default | default: | _ (捨棄模式) |
when 守衛 | 支援 | 支援 |
| 模式類型 | 常數、型別、關係 (C# 9+) | 全部支援 |
| 模式 | 語法 | 範例 |
|---|---|---|
| 常數 | c | case 42:, case "abc": |
| 型別 | T varName | case int i:, case string s: |
| 宣告 | var name | case var x: (永遠匹配) |
| 捨棄 | _ | case _: (default) |
| 關係 | < > <= >= | case >= 18: |
| 邏輯 | and or not | case > 0 and < 100: |
| 屬性 | { Prop: pattern } | case { Age: >= 18 }: |
| Tuple | (p1, p2) | case (true, false): |
| 位置/切片 | [p1, .., p2] | case [1, 2, ..]: |
// 基本
string result = (score >= 60) ? "及格" : "不及格";
// 巢狀 (慎用)
string grade = score >= 90 ? "A" : score >= 80 ? "B" : "C";
// 配合 null 條件
int length = text?.Length ?? 0;
// 唯讀屬性初始化
public string Status => _isActive ? "Active" : "Inactive";
is / switch// is 型別模式 (C# 7+)
if (input is int i) Console.WriteLine(i * 2);
if (input is string { Length: > 10 } s) Console.WriteLine("長字串");
// switch 運算式當作方法主體
public string Classify(int n) => n switch {
< 0 => "負數",
0 => "零",
> 0 => "正數"
};
public static class Guard {
public static void AgainstNull(this T? value, string paramName)
where T : class {
if (value is null) throw new ArgumentNullException(paramName);
}
public static void AgainstNegative(this int value, string paramName) {
if (value < 0) throw new ArgumentOutOfRangeException(paramName);
}
}
// 使用
public void SetAge(int age) {
age.AgainstNegative(nameof(age));
_age = age;
}
switch 運算式搭配 _,新增 enum 值時編譯器警告。if/switch。if (x is A) ... else if (x is B) → x switch { A => ..., B => ... }。switch 運算式需要 break 嗎?A: 不需要。每個模式最多匹配一個分支,無 fall-through。
null 做模式比對?A: case null: 或 null => ...。注意 case var x: 也會匹配 null。
when 守衛能存取外部變數嗎?A: 能,捕捉外部區域變數 (closure)。
case > 0: 需要什麼版本?A: C# 9.0+ (NET 5+)。