C# 2.0 引入 空值合併運算子 ??,提供簡潔語法處理「可為 null 的值型別」或「參考型別」的預設值邏輯。本文說明語法、行為、鏈式用法、與 Nullable<T>、GetValueOrDefault 的關係。
T result = nullableValue ?? defaultValue;
// 等價於
T result = (nullableValue != null) ? nullableValue : defaultValue;
// 參考型別
string msg = null;
string result = msg ?? "預設訊息"; // "預設訊息"
msg = "Hello";
result = msg ?? "預設訊息"; // "Hello"
// 可為 null 的值型別
int? num = null;
int value = num ?? -1; // -1
num = 42;
value = num ?? -1; // 42
string config = GetFromCmd() ?? GetFromEnv() ?? GetFromConfigFile() ?? "內建預設值";
// 依序評估,第一個非 null 即回傳,短路特性保證後續不執行
| 場景 | 程式碼 | 說明 |
|---|---|---|
| 拋出例外 | return value ?? throw new ArgumentNullException(nameof(value)); | C# 7.0+ 支援 throw expression |
| 指派 | x ??= ComputeDefault(); | C# 8.0+ ??= 僅當 x 為 null 時指派 |
| 搭配 ?. 運算子 | var len = obj?.Prop?.Length ?? 0; | 鏈式 null 檢查並提供預設值 |
| Lambda 簡化 | Func | 常用於 LINQ 投影 |
int? 是 Nullable 別名,?? 直接作用於 Nullable<T>,回傳 T(非 Nullable<T>)。num.GetValueOrDefault(-1) 效果相同,但 ?? 可接受任意運算式(含方法呼叫)作為預設值,且短路。default(T) 對值型別回傳 0/false,對參考型別回傳 null;?? default(T) 等同 GetValueOrDefault()。string、class、delegate、array)同樣適用。?? 於非 nullable 值型別:int i = 0; i ?? 1 編譯錯誤,因 int 永不為 null。?? 更易讀、意圖明確。?? 替代 if (x == null) x = default; 或三元運算子。_field = arg ?? throw new ArgumentNullException(nameof(arg));。val = cfg["Key"] ?? env["KEY"] ?? "default";。?? 是 C# 處理 null 的基石語法,配合 ?.、??=、throw expression,能寫出既安全又簡潔的防禦性代碼。