字串處理是 C# 開發的日常。理解 System.String (不可變)、System.Text.StringBuilder (可變緩衝區)、比較選項與記憶體行為,是寫出高效能、正確程式碼的關鍵。本文深度解析核心類別、常用方法、效能陷阱與最佳實務。
一、System.String - 不可變參考型別
特性
- 不可變:任何「修改」操作 (
Replace, Substring, ToUpper, +, String.Concat) 皆**建立新字串**,原字串不變。
- 字元陣列包裝:內部為
char[] (UTF-16),Length 為字元數 (非位元組數)。
- 駐留池:編譯期常值、
String.Intern 字串共享唯一實例,== 比較參考相等時極快。
- 實作介面:
IEnumerable<char>, IComparable, IEquatable<string>...
常用靜態方法
| 方法 | 用途 | 備註 |
IsNullOrEmpty | 檢查 null 或 "" | 最常用防禦檢查 |
IsNullOrWhiteSpace | 檢查 null、空白、空字串 | 含空白、Tab、換行 |
Compare(strA, strB, StringComparison) | 比較大小/相等 | **必指定 StringComparison**,避免文化特性 Bug |
Equals(a, b, StringComparison) | 相等判斷 | 同左,推薦用此而非 == |
Join(sep, values) | 陣列/集合串接 | 高效能,避免迴圈 + |
Concat(args) | 多字串串接 | 編譯器優化 a+b+c 為此 |
Format(fmt, args) | 複合格式化 | 內部用 StringBuilder |
Intern/IsInterned | 駐留池操作 | 極少用,節省重複字串記憶體 |
常用實例方法
| 方法 | 回傳 | 說明 |
IndexOf/LastIndexOf | int | 尋找子字串/字元,**指定 StringComparison.Ordinal** 最快 |
StartsWith/EndsWith | bool | 前綴/後綴檢查,指定 Ordinal |
Contains | bool | .NET Core 2.0+ 多載支援 StringComparison |
Substring(start, len?) | string | 擷取子字串 (新配置) |
AsSpan() | ReadOnlySpan<char> | **零配置**切片,.NET Core 2.1+ 推薦替代 Substring |
Split(sep, options) | string[] | 分割,**指定 RemoveEmptyEntries** 避免空元素 |
Trim/TrimStart/TrimEnd | string | 移除首尾空白字元 (可傳入 char[]) |
Replace(old, new) | string | 全域取代 (新配置) |
ToUpper/ToLower (culture?) | string | **指定 CultureInfo.InvariantCulture** 避免土耳其語 I 陷阱 |
PadLeft/PadRight | string | 填充對齊 |
二、StringComparison - 字串比較的靈魂
永遠在比較/搜尋/StartsWith/EndsWith/Contains/IndexOf 明確指定 StringComparison。
| 列舉值 | 行為 | 適用場景 | 效能 |
| Ordinal | 位元級比較 (區分大小寫) | **內部識別碼、路徑、XML、JSON、Protocol、效能關鍵** | **最快** (單純記憶體比對) |
| OrdinalIgnoreCase | 位元級不分大小寫 (英文 ASCII 規則) | **大小寫不敏感識別碼、HTTP Header、SQL 關鍵字** | 極快 |
| CurrentCulture | 依目前執行緒文化特性語言規則 | **使用者顯示排序、UI 列表排序** | 慢 (語言規則複雜) |
| CurrentCultureIgnoreCase | 同上,不分大小寫 | 使用者輸入比對 | 慢 |
| InvariantCulture | 固定不變文化特性 (英文規則) | **跨文化特性持久化排序、檔案儲存順序** | 中等 |
| InvariantCultureIgnoreCase | 同上,不分大小寫 | 持久化不分大小寫比對 | 中等 |
經典 Bug:土耳其語 I 問題
// 伺服器文化特性為 tr-TR (土耳其語)
"file".ToUpper() == "FILE" // false! 因為 'i' -> 'İ' (帶點), 'I' -> 'ı' (無點)
// 正確
"file".ToUpperInvariant() == "FILE" // true
// 或
string.Equals("file", "FILE", StringComparison.OrdinalIgnoreCase) // true
三、StringBuilder - 可變字串緩衝區
適用場景
- **大量串接** (迴圈中
+=、未知次數拼接)。
- **大字串建構** (XML/JSON/HTML/Log/報表產生)。
- **頻繁修改** (Insert/Remove/Replace 同一緩衝區)。
核心屬性與方法
| 成員 | 說明 |
Capacity | 內部緩衝區大小 (字元數),自動成長 (通常倍增)。**預估長度預先設定** 避免擴容複製。 |
Length | 目前字串長度。 |
Append(...) | 重載極多,**首選串接方式**,支援基礎型別直接格式化。 |
AppendLine() | 加入 Environment.NewLine。 |
AppendFormat(fmt, args) | 複合格式化附加。 |
Insert(index, value) | 插入 (移動後續字元)。 |
Remove(start, len) | 刪除區間。 |
Replace(old, new, start?, count?) | 區間取代 (比 String.Replace 彈性)。 |
Clear() | 長度歸零,**保留 Capacity**,適合重複使用 (物件池模式)。 |
ToString() | 輸出字串 (新配置)。.NET Core 3.0+ 可能共享記憶體 (內部優化)。 |
this[int index] | 索引器讀寫單一字元 (可變!)。 |
效能比較:迴圈串接 10 萬次
// String += : ~1,200 ms, 大量 Gen2 GC
// String.Concat 陣列 : ~15 ms (需預知數量)
// StringBuilder (預設 Capacity) : ~8 ms
// StringBuilder (Capacity=1,000,000) : ~3 ms **最快**
四、現代進階:Span、Memory、String.Create
string.AsSpan() / StringBuilder.AsSpan():零配置切片,**高效能解析/搜尋首選**。
String.Create(len, state, (span, state) => ...):.NET Core 2.1+,**單次配置直接寫入字元**,極致效能 (如自訂格式化、Base64 編碼)。
ReadOnlySpan<char> 取代 string 傳遞:避免 Substring 配置,解析器/Tokenizer 標準做法。
五、最佳實務清單
- 預設用
string:不可變、語意清晰、小量操作零負擔。
- 迴圈/大量拼接用
StringBuilder:**預設 Capacity** 或 new StringBuilder(estimatedLength)。
- 所有比較/搜尋/StartsWith/EndsWith/Contains/IndexOf **必指定
StringComparison.Ordinal 或 OrdinalIgnoreCase**。
- 大小寫轉換用
ToUpperInvariant() / ToLowerInvariant() 或指定 CultureInfo.InvariantCulture。
- 分割用
Split(sep, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) (.NET 5+)。
- 高效能解析/Tokenizer:全程用
ReadOnlySpan<char>,最終才 ToString() 輸出必要結果。
- 避免
string.Format 熱路徑:改用 StringBuilder.AppendFormat、String.Create 或插值字串 $"" (編譯器優化)。
- 物件池重用 StringBuilder:
ArrayPool<char> 或自訂 ObjectPool<StringBuilder> (ASP.NET Core 內建)。
結語
String 以**不可變**換取執行緒安全、字面值共享、語意簡潔;StringBuilder 以**可變緩衝區**解決大量修改效能問題。掌握 StringComparison.Ordinal、InvariantCulture、Span、String.Create 等現代工具,即能在正確性與效能間遊刃有餘。