三種常見寫法
string s = GetString();
// 1. Length 檢查
bool isEmpty1 = (s != null && s.Length == 0);
// 2. String.Empty 比較
bool isEmpty2 = (s == String.Empty);
// 3. 字面值比較
bool isEmpty3 = (s == "");
.NET 內部機制深度剖析 (參考源碼)
// String 類別關鍵實作片段 (簡化)
public sealed class String : IComparable, ...
{
public static readonly string Empty = ""; // 靜態建構子初始化
public static bool operator ==(string a, string b)
{
return Equals(a, b);
}
public static bool Equals(string a, string b)
{
if (a == b) return true; // 參考相等快速通道
if (a != null && b != null) // 雙非 null
return EqualsHelper(a, b); // 逐字元比較
return false;
}
private static unsafe bool EqualsHelper(string a, string b)
{
int len = a.Length;
if (len != b.Length) return false; // 長度不同直接 false
// ... 逐字元比較 (SIMD 優化)
}
public int Length
{
get { return this.InternalLength(); } // 內部欄位直接讀取,極快
}
}
效能與行為比較
| 方法 | Null 安全 | 建立物件 | 比較步驟 | 相對速度 | 推薦度 |
s.Length == 0 | 需自行檢查 null | 無 | 1. 讀取 Length 欄位 2. 整數比較 | ⭐⭐⭐⭐⭐ 最快 | ✅ 首選 (配合 null 檢查) |
s == String.Empty | 安全 | 無 (單例) | 1. 參考比較 2. 長度比較 3. 逐字元比較 | ⭐⭐⭐ | 可接受 |
s == "" | 安全 | 每次建立新字串物件 (舊版) / 編譯器優化為 Empty | 同 String.Empty + 可能建立物件 | ⭐⭐ | ❌ 不推薦 |
string.IsNullOrEmpty(s) | 安全 | 無 | 1. null 檢查 2. Length == 0 | ⭐⭐⭐⭐ | ✅ 標準庫推薦 |
string.IsNullOrWhiteSpace(s) | 安全 | 無 | 含空白字元檢查 | ⭐⭐⭐ | 視需求 |
為何 Length 最快?
- 直接記憶體讀取:
Length 為儲存在物件標頭後的整數欄位,無方法呼叫開銷 (JIT 內聯)。
- 整數比較:CPU 單指令完成,分支預測友善。
- 避免虛擬呼叫:
Equals 為虛擬方法,涉及查表與分派。
- 短路優化:
s != null && s.Length == 0 先檢查 null,避免例外。
現代 C# 最佳實踐 (C# 6.0+)
// 模式比對 (C# 7.0+)
bool isEmpty = s is { Length: 0 }; // 隱含 null 檢查,極簡潔
// 擴充方法封裝 (專案通用)
public static class StringExtensions
{
public static bool IsNullOrEmpty(this string s)
=> s == null || s.Length == 0;
public static bool IsNullOrWhiteSpace(this string s)
=> string.IsNullOrWhiteSpace(s);
}
// 使用
if (input.IsNullOrEmpty()) return;
避坑指南
- 直接呼叫 s.Length:若 s 為 null 會拋
NullReferenceException,必須先檢查 null。
- 大量迴圈中:
Length == 0 顯著優於 == "" (避免物件配置/比較開銷)。
- Framework 版本:.NET Core / .NET 5+ 對
== "" 編譯器優化更激進,但 Length 仍為理論最優。
- 語意清晰:
string.IsNullOrEmpty 最具可讀性,效能差異微乎其微 (內部即 Length 檢查)。
結論
// 專案標準建議
if (string.IsNullOrEmpty(s)) { ... } // 一般業務邏輯,可讀性最佳
if (s != null && s.Length == 0) { ... } // 熱路徑/極致效能場景
if (s is { Length: 0 }) { ... } // C# 7+ 現代語法,兼具簡潔與效能