三元運算子 condition ? trueExpr : falseExpr 強制雙分支。處理「若為 null 則用預設值」時常寫成:
// 重複存取集合/屬性,易拼錯鍵名且效能稍差
string param = Request.Params["key"] == null ? defaultVal : Request.Params["key"];
// 屬性 getter 中
public string Value { get { return _value == null ? string.Empty : _value; } }
?? 運算子誕生C# 2.0 隨 Nullable<T> 引入 空合併運算子 ??:
int? a = 1;
int? b = null;
int c = a ?? 100; // 1
int d = b ?? 100; // 100
int e = a + b ?? -1; // (a+b) 為 null -> -1
語法:left ?? right。若 left 非 null 則結果為 left,否則為 right。right 型別需隱含轉換為結果型別。
// 原寫法
string p = Request.Params["key"];
if (p == null) p = defaultVal;
// ?? 版 (單次存取、無暫存變數)
string p = Request.Params["key"] ?? defaultVal;
// ViewState / Session / Dictionary 同理
var data = ViewState["Key"] ?? DefaultValue;
// 原寫法
public string Name
{
get { return _name == null ? string.Empty : _name; }
}
// ?? 版
public string Name => _name ?? string.Empty; // C# 6.0 expression-bodied
// 使用者設定 → 系統預設 → 硬編碼預設
string config = userSetting ?? systemDefault ?? "HardCodedDefault";
int?, DateTime?, MyStruct?。string, class, delegate, array (本身可為 null)。注意:非可空實值型別 (int, DateTime) 無法直接使用 ??,因永不為 null。若需類似邏輯請用可空型別。
??=` 賦值運算子 (C# 8.0+)
// 僅當左邊為 null 時賦值
_config ??= LoadConfig(); // 等同 if (_config == null) _config = LoadConfig();
?? 是專為「Null 預設值」設計的語法糖,消除三元運算子的冗餘與重複存取風險,讓防禦性程式碼更簡潔、可讀、安全。凡見「== null ? fallback : expr」即可重構為「expr ?? fallback」。