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

.NET 字串深度解析:比較操作陷阱與進階應用(下)

     編輯:關於.NET

前言

前兩節介紹了字串的「恆定性」與「駐留性」。若你以為已掌握字串精髓,請繼續閱讀第 3、4 節,驗證你的理解深度。

第三節:有趣的比較操作——10 組代碼實戰

以下 10 段代碼透過值比較(Equals)與引用比較(ReferenceEquals),揭示字串駐留機制的微妙行為。建議先自行預測輸出,再對照解析。

代碼一:字面量直接賦值

string a = "str_1";
string b = "str_1";
Response.Write(a.Equals(b));        // True:值相同
Response.Write(ReferenceEquals(a,b)); // True:駐留機制,引用同一記憶體

代碼二:變量拼接 vs 字面量

string a = "str_1str_2";
string b = "str_1";
string c = "str_2";
string d = b + c;
Response.Write(a.Equals(d));        // True:值相同
Response.Write(ReferenceEquals(a, d)); // False:變量拼接產生新物件,駐留失效

代碼三:常量拼接

string a = "str_1str_2";
string b = "str_1" + "str_2";
Response.Write(a.Equals(b));        // True
Response.Write(ReferenceEquals(a, b)); // True:編譯期常量折疊,駐留生效
關鍵點:若為「常量 + 變量」拼接,駐留機制失效。

代碼四:String.Copy 產生新物件

string a = "str_1";
string b = String.Copy(a);
Response.Write(a.Equals(b));        // True
Response.Write(ReferenceEquals(a, b)); // False:Copy 產生新物件

代碼五:String.Intern 手動駐留

string a = "str_1";
string b = String.Copy(a);
b = String.Intern(b);
Response.Write(a.Equals(b));        // True
Response.Write(ReferenceEquals(a, b)); // True:Intern 將 b 駐留至字串池

代碼六:== 運算子與引用比較

string a = "str_1";
string b = String.Copy(a);
string c = "str_1";
Response.Write((object)a == (object)b); // False:強制轉 object,比較引用
Response.Write((object)a == (object)c); // True:駐留機制,引用相同

代碼七:== 運算子的重載行為

string a = "str_1";
string c = "str_1";
Response.Write(a == c); // True

解析:雖然 string 為引用類型,但 == 已被重載為 Equals,故比較的是值而非引用位址。

代碼八:new string() 建構式

string a = "a";
string b = new string('a', 1);
Response.Write(a.Equals(b));        // True:值相同
Response.Write(ReferenceEquals(a, b)); // False:new 建構式繞過駐留

代碼九:Intern 修正 new string()

string a = "a";
string b = new string('a', 1);
Response.Write(a.Equals(string.Intern(b)));  // True
Response.Write(ReferenceEquals(a, string.Intern(b))); // True:Intern 強制駐留

代碼十:Substring 產生新物件

string a = "str";
string b = "str_2".Substring(0,3);
Response.Write(a.Equals(b));        // True
Response.Write(ReferenceEquals(a, b)); // False:Substring 產生新物件

思考題:此段代碼共產生幾個 string 物件?(答案:3 個——"str"、"str_2"、"str")

第四節:藝海拾貝——常見問題彙總

1. "string = " vs "new string()" 差異

string test = "a";           // 編譯期放入常量池,有駐留
string test = new string('a', 1); // 運行期堆上建立,無駐留

2. string vs String

string 是 C# 基元類型關鍵字,String 是 System.String 完整類型名。編譯為 IL 時完全相同:

// C#
string str_test = "test";
System.String Str_test = "test";

// IL
ldstr "test"
stloc.0
ldstr "test"
stloc.1

差異僅在語義層面:string 類似 int 的基元別名;System.String 是 FCL 類型名,兩者直接對應。

3. StringBuilder 高效構建字串

適用於大量字串拼接場景。StringBuilder 內部維護可變字元陣列 m_StringValue,ToString() 返回其引用。若修改後再次呼叫 ToString(),會建立新字串,原返回字串不受影響。

兩大核心欄位:

  • m_MaxCapacity:最大容量(預設 Int32.MaxValue),指定後不可變
  • m_StringValue:內部字元陣列,實際字串存儲

掌握這些秘密,你對 string 的認識將全面升級!

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