程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> .Net Framework: 字符串的駐留(String Interning)

.Net Framework: 字符串的駐留(String Interning)

編輯:C#入門知識

關於字符串的駐留的機制,對於那些了解它的人肯定會認為很簡單,但是我相信會有很大一部分人對它存在迷惑。在開始關於字符串的駐留之前,先給出一個有趣的Sample: 
   
  Code Snip: 
  
  static void Main(string[] args) 
   { 
   string str1 = "ABCD1234"; 
   string str2 = "ABCD1234"; 
   string str3 = "ABCD"; 
   string str4 = "1234"; 
   string str5 = "ABCD" + "1234"; 
   string str6 = "ABCD" + str4; 
   string str7 = str3 + str4; 
   
   Console.WriteLine("string str1 = "ABCD1234";"); 
   Console.WriteLine("string str2 = "ABCD1234";"); 
   Console.WriteLine("string str3 = "ABCD";"); 
   Console.WriteLine("string str4 = "1234";"); 
   Console.WriteLine("string str5 = "ABCD" + "1234";"); 
   Console.WriteLine("string str6 = "ABCD" + str4;"); 
   Console.WriteLine("string str7 = str3 + str4;"); 
   
   Console.WriteLine(" object.ReferenceEquals(str1, str2) = {0}", object.ReferenceEquals(str1, str2)); 
   Console.WriteLine("object.ReferenceEquals(str1, "ABCD1234") = {0}", object.ReferenceEquals(str1, "ABCD1234")); 
   
   Console.WriteLine(" object.ReferenceEquals(str1, str5) = {0}", object.ReferenceEquals(str1, str5)); 
   Console.WriteLine("object.ReferenceEquals(str1, str6) = {0}", object.ReferenceEquals(str1, str6)); 
   Console.WriteLine("object.ReferenceEquals(str1, str7) = {0}", object.ReferenceEquals(str1, str7)); 
   
   Console.WriteLine(" object.ReferenceEquals(str1, string.Intern(str6)) = {0}", object.ReferenceEquals(str1, string.Intern(str6))); 
   Console.WriteLine("object.ReferenceEquals(str1, string.Intern(str7)) = {0}", object.ReferenceEquals(str1, string.Intern(str7))); 
   } 
   
   
  下邊是輸出的結果: 
  \ 
  接下來我們來逐句地分析這段代碼: 
   
  首先我們創建了兩個完全相同的字符串(ABCD1234),並將他們分別賦予了兩個字符創變量——str1和str2。然後把它們傳給了object.ReferenceEquals。我們知道object.ReferenceEquals是用於確定兩個變量是否具有相同的引用——換句話說,當兩個變量引用的是同一塊托管推的內存快的時候,返回True,否則返回False。 
   
  string str1 = "ABCD1234"; 
  string str2 = "ABCD1234"; 
  object.ReferenceEquals(str1, str2)= True; 
  object.ReferenceEquals(str1, "ABCD1234")) = True; 
   
  令我們感到奇怪的是,當我們分別創建的引用類型兩個變量——string是引用類型。照理說CLR會在托管堆(Managed Heap)中為它們分配兩段內存快,他們不可能具有相同的引用才對,但是為什麼object.ReferenceEquals 方法會返回True呢。而對於第二個比較——一個字符串變量和一個和他具有相同內容的字符串("ABCD1234";)直接進行比較,按照我們對CLR內存的分配的一般理解,應該是CLR首先會在托管堆中為這段字符串("ABCD1234")分配內存快,然後把相對應的引用傳遞給object.ReferenceEquals方法(由於分配在托管堆的這段字符串並沒有被任何變量引用,所以當垃圾回收的時候會被回收掉),所以無論如何也不應該返回True。 
   
  我們先把問題留到最後,接著分析我們的Sample。上面們對字符串變量之間以及變量與字符串之間進行了比較,如果我們對一個字符串變量和一個動態創建的字符串(通過+Operator把兩個字符串連接起來)進行比較,結果又會如何呢?我們來看看下面的偽代碼演示: 
   
  string str3 = "ABCD"; 
  string str4 = "1234"; 
  string str5 = "ABCD" + "1234"; 
  string str6 = "ABCD" + str4; 
  string str7 = str3 + str4; 
  object.ReferenceEquals(str1, str5) = True 
  object.ReferenceEquals(str1, str6) = False 
  object.ReferenceEquals(str1, str7)) = False 
   
  在上面的例子中,我們用三種不同的方式創建了3個字符串變量(str5,str6,str7)——string+string;string+variable;variable+variable。然後分別和我們已經創建的、和它們具有相同字符串“值”的變量(str1)作比較。同樣令我們感到奇怪的是第一個返回True,而後兩個則為False。帶著這些疑惑我們來看看對於string這一特殊的類型說采用的特殊的

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved