最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#?基礎數(shù)據(jù)類型之字符串類型詳解

 更新時間:2026年05月25日 08:44:38   作者:少年。  
C#字符串作為引用類型卻常被當作值類型使用,探討其不可變性、字符串駐留及常用操作,本文給大家介紹C#?基礎數(shù)據(jù)類型之字符串類型,感興趣的朋友一起看看吧

字符串不就是一串字符嗎,能有多少花樣?實際上,字符串作為引用類型,卻常常表現(xiàn)出值類型的“錯覺”,在拼接、比較、內(nèi)存開銷等方面藏著不少坑。這篇就來聊聊 C# 中的 string,從本質到常用騷操作,幫你把字符串用得明明白白。

  • 字符串的本質:它到底是值類型還是引用類型?
  • 不可變性與字符串駐留:為什么修改字符串會創(chuàng)建新對象?
  • 常用操作與最佳實踐:拼接、比較、格式化怎么選?
  • 性能陷阱與優(yōu)化:什么時候該用 StringBuilder?
  • 字符串與 Span :新一代高性能字符串處理方式

一、字符串的本質

1.1 什么是字符串

在 C# 中,string? 是 System.String? 的別名,表示一個 不可變的字符序列。它雖然是引用類型,但設計上模仿了值類型的語義(如比較相等性時比較內(nèi)容而非引用)。

string greeting = "Hello, World!";
Console.WriteLine(greeting.Length); // 13

代碼解析:

  • string:定義一個字符串變量,本質是 System.String 類的實例。
  • "Hello, World!" :字符串字面量,編譯器會將其放入字符串駐留池。
  • Length:字符串的長度屬性,表示字符數(shù)(注意 string? 的索引是基于 Char? 的,對于包含代理項的 Unicode 字符,一個“字符”可能占兩個 Char)。

1.2 字符串是引用類型,但行為像值類型

字符串屬于引用類型,分配在堆上,變量存儲的是引用。但它重寫了 Equals 方法,讓比較時比較內(nèi)容。此外,字符串的不可變性使得它經(jīng)常被當作值類型來使用。

string a = "hello";
string b = "hello";
Console.WriteLine(object.ReferenceEquals(a, b)); // True(因為字符串駐留)
Console.WriteLine(a == b); // True

核心知識點:字符串比較時,==? 運算符被重載為比較內(nèi)容,而 ReferenceEquals? 比較引用。由于 字符串駐留 機制,相同字面量的字符串常常指向同一塊內(nèi)存。

二、字符串的不可變性

2.1 為什么字符串不可變?

字符串一旦創(chuàng)建,其內(nèi)部的字符數(shù)組就不能被修改。任何修改操作(如 ToUpper?、Replace、拼接)都會生成一個新的字符串對象,而原字符串保持不變。

string original = "hello";
string modified = original.ToUpper();
Console.WriteLine(original); // "hello"
Console.WriteLine(modified); // "HELLO"
Console.WriteLine(object.ReferenceEquals(original, modified)); // False

劃重點: 不可變性保證了字符串是線程安全的,多個線程可以共享同一個字符串實例,無需擔心數(shù)據(jù)被意外修改。

2.2 字符串駐留(String Interning)

公共語言運行時(CLR)維護一個字符串駐留池,對于編譯時確定的字面量字符串,會自動駐留。運行時可手動調用 string.Intern 將字符串放入池中。

string s1 = "Hello";
string s2 = "Hello";
string s3 = new string("Hello".ToCharArray());
Console.WriteLine(ReferenceEquals(s1, s2)); // True(編譯時駐留)
Console.WriteLine(ReferenceEquals(s1, s3)); // False(s3是動態(tài)創(chuàng)建的字符串)
s3 = string.Intern(s3);
Console.WriteLine(ReferenceEquals(s1, s3)); // True(手動駐留后相同)

常見坑: 大量動態(tài)拼接的字符串如果不手動駐留,會占用過多內(nèi)存。適時使用 string.Intern 可以減少重復字符串的內(nèi)存開銷,但過度使用反而會增加駐留池的壓力。

三、字符串常用操作

3.1 拼接

方式特點適用場景
?+ 運算符簡單直接,每次拼接創(chuàng)建新對象少量拼接(< 5次)
?string.Concat內(nèi)部使用 StringBuilder 優(yōu)化?不,直接拼接明確知道拼接個數(shù)時
?string.Format格式字符串,可讀性好帶格式化的拼接
?$ 字符串插值語法糖,編譯后等同 string.FormatC# 6.0 起推薦

StringBuilder | 可變緩沖區(qū),頻繁修改性能高 | 循環(huán)中大量拼接 |

// 少量拼接,用插值
var msg = $"Hello, {name}! You have {count} messages.";
// 循環(huán)拼接,用 StringBuilder
var sb = new StringBuilder();
foreach (var item in items)
{
    sb.Append(item).Append(", ");
}
string result = sb.ToString().TrimEnd(',', ' ');

3.2 比較

推薦使用 string.Equals? 或靜態(tài)方法,并指定 StringComparison 選項。

string a = "hello";
string b = "HELLO";
bool ignoreCase = a.Equals(b, StringComparison.OrdinalIgnoreCase);
bool exact = string.Compare(a, b, StringComparison.Ordinal) == 0;

劃重點: 在.NET Core/.NET 5+ 中,默認的 ==? 比較采用 序數(shù)比較(Ordinal),行為與 StringComparison.Ordinal? 一致。但在 .NET Framework 中默認使用當前區(qū)域性進行語言比較,可能導致意外的排序結果。始終顯式指定比較模式,以避免跨平臺差異。

3.3 格式化

?string.Format 和字符串插值支持復合格式,包括對齊和格式化字符。

double price = 123.456;
Console.WriteLine($"Price: {price,10:C2}"); // 右對齊,寬度10,貨幣格式
// 輸出:Price:   ¥123.46

四、性能陷阱與優(yōu)化

4.1 循環(huán)中的字符串拼接

每次用 + 拼接都會創(chuàng)建新字符串,在循環(huán)中會引發(fā)嚴重的性能和內(nèi)存問題。

// 錯誤做法
string s = "";
for (int i = 0; i < 100000; i++)
{
    s += i.ToString(); // 每次循環(huán)都分配新字符串
}
// 正確做法
var sb = new StringBuilder();
for (int i = 0; i < 100000; i++)
{
    sb.Append(i);
}
string result = sb.ToString();

【提示】 少量拼接(比如 3-5 次)直接用插值或 +?,編譯器會優(yōu)化成 string.Concat?,性能不差。但一旦進了循環(huán),務必用 StringBuilder,否則垃圾回收(GC)會教你做人。

4.2 字符串的截取與內(nèi)存

?Substring? 方法在 .NET Framework 中返回的字符串與原字符串共享內(nèi)部的字符數(shù)組,可能導致大對象被長期引用。但在 **.NET Core / .NET 5+ ** 中,Substring 每次都會創(chuàng)建新的字符數(shù)組,不再共享內(nèi)存。

string filePath = @"C:\Users\Alice\Documents\report.docx";
// .NET Core 中,Substring 會分配新內(nèi)存
string fileName = filePath.Substring(filePath.LastIndexOf('\\') + 1);

4.3 使用 Span<char>? 和 ReadOnlySpan<char> 處理字符串

當需要在不分配堆內(nèi)存的情況下對字符串進行切片、解析時,Span<T> 是神器。

ReadOnlySpan<char> span = "Hello, World".AsSpan();
ReadOnlySpan<char> slice = span.Slice(0, 5); // 指向 "Hello",無堆內(nèi)存分配
Console.WriteLine(slice.ToString()); // 但調用 ToString 還是會在堆上分配字符串

劃重點: Span<T> 可以避免大量臨時字符串的分配,尤其在解析配置文件、日志行等場景下性能飛躍。但它只能在棧上使用,不能作為類的字段。

五、常用字符串方法一覽

方法功能是否修改原字符串
?Length獲取字符數(shù)只讀屬性
?ToUpper()?/ToLower()大小寫轉換返回新字符串
?Trim()移除首尾空白返回新字符串
?Split(char[])分割字符串返回字符串數(shù)組
?Substring(int, int)提取子字符串返回新字符串
?Replace(string, string)替換子串返回新字符串
?Contains(string)判斷是否包含子串只讀取
?IndexOf(string)查找子串位置只讀取

常見坑: Replace? 和 Trim 等返回新字符串,如果忘了接收返回值,原字符串不會改變。

string text = "  hello  ";
text.Trim(); // 錯誤!原字符串不變
string trimmed = text.Trim(); // 正確,用 trimmed 接收新值

六、字符串與編碼

C# 的 string? 內(nèi)部使用 UTF-16 編碼存儲,即每個字符至少占 2 個字節(jié)。當與外部二進制數(shù)據(jù)交互時,需要使用 Encoding 類進行轉換。

string text = "Hello, 世界";
byte[] utf8Bytes = Encoding.UTF8.GetBytes(text);
string decoded = Encoding.UTF8.GetString(utf8Bytes);

性能注意: Encoding.GetBytes? 和 GetString? 涉及內(nèi)存分配,對于高吞吐場景,可以使用 Encoding.GetBytes? 的重載,將數(shù)據(jù)寫入 Span<byte> 緩沖區(qū)。

七、總結

字符串雖然簡單,但用不好就會成為性能瓶頸。記住幾個核心原則:

  • 不可變性是雙刃劍:保證了線程安全,但拼接會生成大量臨時對象。
  • 少量拼接用插值,循環(huán)拼接用 ?StringBuilder?。
  • 比較字符串時務必指定 ?StringComparison?,避免跨平臺行為差異。
  • 在 .NET Core / .NET 5+ 中,??Substring?? 不再共享內(nèi)存,可以放心使用。
  • 善用 ?Span<T>? 實現(xiàn)零分配的字符串切片和解析。

最后:字符串是門大學問,搞清楚了不可變性和駐留機制,能幫你避開大部分坑。下次遇到字符串拼接變慢,別猶豫,換上 StringBuilder 再說。

到此這篇關于C# 基礎數(shù)據(jù)類型:字符串類型的文章就介紹到這了,更多相關C# 字符串類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • WinForm中跨線程操作UI的解決方案匯總

    WinForm中跨線程操作UI的解決方案匯總

    在開發(fā)WinForm應用程序時,經(jīng)常會遇到需要在線程間操作UI的情況,直接從非UI線程更新UI控件會導致異常,因此我們需要采取適當?shù)姆椒▉戆踩剡M行這些操作,本文總結了幾種常見的解決方法,并對其優(yōu)缺點進行了分析,需要的朋友可以參考下
    2025-06-06
  • C# winform打開Excel文檔的方法總結(必看篇)

    C# winform打開Excel文檔的方法總結(必看篇)

    下面小編就為大家?guī)硪黄狢# winform打開Excel文檔的方法總結(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • C# windows語音識別與朗讀實例

    C# windows語音識別與朗讀實例

    這篇文章主要為大家詳細介紹了C# windows語音識別與朗讀實例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • c# RSA非對稱加解密及XML&PEM格式互換方案

    c# RSA非對稱加解密及XML&PEM格式互換方案

    這篇文章主要介紹了c# RSA非對稱加解密及XML&PEM格式互換方案,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2020-12-12
  • C# 顯示、隱藏窗口對應的任務欄

    C# 顯示、隱藏窗口對應的任務欄

    WPF中全屏窗口,會自動隱藏任務欄,那非全屏窗口如何隱藏任務欄?甚至有沒有一種場景,隱藏任務后自定義一套系統(tǒng)任務欄來顯示?這篇文章主要介紹了C# 顯示、隱藏窗口對應的任務欄,需要的朋友可以參考下
    2021-10-10
  • C#獲取Excel文件所有文本數(shù)據(jù)內(nèi)容的示例代碼

    C#獲取Excel文件所有文本數(shù)據(jù)內(nèi)容的示例代碼

    獲取上傳的?EXCEL?文件的所有文本信息并存儲到數(shù)據(jù)庫里,可以進一步實現(xiàn)對文件內(nèi)容資料關鍵字查詢的全文檢索,有助于我們定位相關文檔,本文詳細介紹了C#獲取Excel文件所有文本數(shù)據(jù)內(nèi)容實現(xiàn)步驟和代碼,需要的朋友可以參考下
    2024-07-07
  • c#讀取excel方法實例分析

    c#讀取excel方法實例分析

    這篇文章主要介紹了c#讀取excel方法,實例分析了C#讀取excel文件的原理與相關技巧,需要的朋友可以參考下
    2015-06-06
  • C# 結合 Javascript 測試獲取天氣信息

    C# 結合 Javascript 測試獲取天氣信息

    本文將介紹如何使用 C# 并結合 JavaScript 獲取天氣信息,獲取的數(shù)據(jù)來源于360瀏覽器首頁數(shù)據(jù),對C# 獲取天氣信息示例代碼感興趣的朋友一起看看吧
    2024-08-08
  • C#訪問SqlServer設置鏈接超時的方法

    C#訪問SqlServer設置鏈接超時的方法

    這篇文章主要介紹了C#訪問SqlServer設置鏈接超時的方法,涉及CommandTimeout屬性的相關設置技巧,非常簡單實用,需要的朋友可以參考下
    2015-06-06
  • WPF中NameScope的查找規(guī)則詳解

    WPF中NameScope的查找規(guī)則詳解

    這篇文章主要給大家介紹了關于WPF中NameScope的查找規(guī)則的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-10-10

最新評論

宝应县| 碌曲县| 德令哈市| 江阴市| SHOW| 德令哈市| 高清| 望都县| 太仆寺旗| 阳原县| 平和县| 分宜县| 平顶山市| 济源市| 平罗县| 环江| 双城市| 甘洛县| 汽车| 永定县| 托里县| 章丘市| 互助| 资讯 | 出国| 淅川县| 桑植县| 高唐县| 滁州市| 香河县| 枣强县| 钦州市| 凤翔县| 徐水县| 射阳县| 洛隆县| 科技| 枣阳市| 沐川县| 上思县| 望江县|