首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> C# 入門

C# 字串完整指南:建立、不可變性、常用方法、格式化、插值與效能最佳化

     編輯:C# 入門

C# 字串完整指南:建立、不可變性、常用方法、格式化、插值與效能最佳化

字串 是 C# 中使用最頻繁的型別之一。string(System.String 別名)是不可變的參考型別,採用 UTF-16 編碼。理解字串特性、掌握核心 API、避免效能陷阱,是寫出高品質 C# 程式的基本功。

字串建立方式

// 1. 字串常值
string s1 = "Hello World";
string s2 = @"C:\Path\To\File"; // 逐字字串:不處理逸出字元,可跨行

// 2. 建構函式
char[] chars = { 'H', 'e', 'l', 'l', 'o' };
string s3 = new string(chars);
string s4 = new string('*', 10); // "**********"

// 3. 串連
string s5 = "Hello" + " " + "World";
string s6 = string.Concat("Hello", " ", "World");

// 4. 插值字串 (C# 6+)
var name = "Alice"; var age = 30;
string s7 = $"Name: {name}, Age: {age}";

// 5. 格式化
string s8 = string.Format("{0:C}", 1234.56); // "$1,234.56"
string s9 = string.Format("{0:yyyy-MM-dd}", DateTime.Now);

// 6. StringBuilder (高效能建立)
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++) sb.Append(i).Append(',');
string s10 = sb.ToString();

不可變性與效能陷阱

字串不可變:任何「修改」操作都會建立新字串實例。

// 糟糕:迴圈中串連,產生 1000 個中間字串,GC 壓力大
string bad = "";
for (int i = 0; i < 1000; i++) bad += i.ToString();

// 正確:StringBuilder
var sb = new StringBuilder(1000 * 4); // 預估容量
for (int i = 0; i < 1000; i++) sb.Append(i);
string good = sb.ToString();

經驗法則:固定次數串連用 + / 插值;迴圈/不定次數用 StringBuilder。

核心屬性與方法速查

分類成員說明
屬性Length字元數 (UTF-16 代碼單元數)
Chars[int]索引器存取單一字元 (唯讀)
搜尋IndexOf/LastIndexOf尋找字元/子字串位置,支援起始索引、比較選項
Contains是否包含子字串 (C# 7.0+ 支援 StringComparison)
StartsWith/EndsWith前綴/後綴比對
IndexOfAny尋找任一字元位置
擷取Substring擷取子字串 (起始、長度)
Split分割字串陣列,支援移除空白項、限制數量
Remove移除指定範圍字元
Trim/TrimStart/TrimEnd移除前導/尾隨空白或指定字元
修改(回傳新字串)Replace取代字元/子字串
Insert插入子字串
ToUpper/ToLower大小寫轉換 (文化特性敏感)
PadLeft/PadRight填充字元至指定長度
比較Equals相等比較,支援 StringComparison
Compare排序比較,支援文化特性、忽略大小寫
CompareTo實作 IComparable
轉換ToCharArray轉字元陣列
Join串連陣列元素 (靜態方法)
Format複合格式化 (靜態方法)

字串比較:文化特性與序數比較

關鍵建議:明確指定 StringComparison,避免預設文化特性導致 Bug:

// 檔案路徑、XML 標籤、內部識別碼:用序數比較 (快、確定)
if (path.EndsWith(".config", StringComparison.OrdinalIgnoreCase)) { }

// 使用者輸入、顯示用排序:用目前文化特性
if (userInput.Equals("admin", StringComparison.CurrentCultureIgnoreCase)) { }

// 內部邏輯、不區分文化特性:OrdinalIgnoreCase 最安全

格式化與插值進階

標準格式字串

// 數值
1234.5.ToString("C")      // "$1,234.50" (貨幣)
1234.5.ToString("F2")     // "1234.50" (固定小數)
1234.5.ToString("N")      // "1,234.50" (千分位)
0.1234.ToString("P")      // "12.34 %" (百分比)
42.ToString("X")          // "2A" (十六進位)

// 日期時間
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") // "2024-01-15 14:30:45"
DateTime.Now.ToString("o")                   // ISO 8601 "2024-01-15T14:30:45.1234567"
DateTime.Now.ToString("r")                   // RFC 1123 "Mon, 15 Jan 2024 14:30:45 GMT"

// 自訂格式
42.ToString("D5")           // "00042" (補零)
1234.ToString("##,##0")     // "1,234" (千分位)

插值字串進階

var price = 1234.56;
var date = DateTime.Now;

// 格式指定
$"Price: {price:C2}"           // "Price: $1,234.56"
$"Date: {date:yyyy-MM-dd}"     // "Date: 2024-01-15"

// 對齊
$"|{name,-10}|{age,3}|"        // 左對齊 10 寬、右對齊 3 寬

// 條件運算式
$"Status: {(isActive ? "Active" : "Inactive")}"

// 逐字插值 (C# 11+)
$@"
    SELECT * FROM Users
    WHERE Name = {name}
    AND Age > {minAge}
";

StringBuilder 最佳實踐

// 1. 預估容量避免擴容
var sb = new StringBuilder(estimatedLength);

// 2. 連結鏈式呼叫
sb.Append("Header").AppendLine().Append(data).AppendLine("Footer");

// 3. 重複使用 (清除而非新建)
sb.Clear(); // 長度歸零,容量保留
sb.Append(newData);

// 4. 附加格式化
sb.AppendFormat("User: {0}, ID: {1}", name, id);

// 5. 移除尾端分隔符
if (sb.Length > 0) sb.Length--; // 移除最後一字元

Span 與記憶體效能

.NET Core 2.1+ ReadOnlySpan<char> 避免子字串配置:

ReadOnlySpan span = "Hello World".AsSpan();
var world = span.Slice(6); // 無配置,指向原字串記憶體
Console.WriteLine(world.ToString()); // 需要字串時才 ToString()

// 解析不配置
if (int.TryParse(span.Slice(0, 5), out int num)) { }

常見問題 FAQ

Q: 為什麼字串設計為不可變?

A: 執行緒安全、安全性(字串內部化、哈希表鍵)、最佳化(字串驻留、共享)、簡化記憶體管理。

Q: string vs String?

A: string 是 C# 關鍵字(型別別名),String 是 FCL 型別名稱。功能相同,慣例:變數宣告用 string,靜態方法用 String(如 String.Compare)。

Q: 如何高效移除字串中的特定字元?

// 悪劣:多次 Replace
s = s.Replace("a", "").Replace("b", "").Replace("c", "");

// 良好:StringBuilder 逐字元檢查
var sb = new StringBuilder(s.Length);
foreach (char c in s) if (!removeSet.Contains(c)) sb.Append(c);

Q: 字串驻留 是什麼?

A: 編譯期常值字串自動駐留;執行期可用 string.Intern/IsInterned 手動管理。相同內容駐留字串共用同一實例,ReferenceEquals 為 true。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved