2015-10-06 145 views
2

如圖所示 here,在運行時創建的字符串不能被禁用。參考字符串對象

然而,下面的代碼:

class Program { 
    static void Main(string[] args) 
    { 
     string s1 = "Programming Is Fun"; 
     string s3 = s1.ToString(); 
     Console.WriteLine(Object.ReferenceEquals(s1, s3)); 
    } 
} 

給出(VS 2015):

True 

所以,它是指定在某種程度上哪些字符串在運行時產生?

順便說一句:

的代碼:

using System; 
using System.Text; 

class Program { 
    static void Main(string[] args) 
    { 
    string s1 = "hop"; 
    StringBuilder s2 = new StringBuilder(s1); 
    string s3 = s2.ToString(); 
    Console.WriteLine(Object.ReferenceEquals(s1, s3)); 
    } 
} 

給出(VS 2015):

False 
在相反

到單聲道其給出

True 
(版本4.0.2)。

請參閱working example

+2

's3'是引用與s1'相同的字符串的變量,'s1.ToString()'只返回'this',所以它不會創建新的字符串。 [MSDN](https://msdn.microsoft.com/en-us/library/8tc6ws5s(V = vs.110)的.aspx)。 –

+4

'string.ToString()'什麼都不做。它返回對原始字符串的引用。 'StringBuilder.ToString()'將生成一個字符串並返回其引用。生成過程可能會有所不同,如果在單聲道中沒有對「StringBuilder」進行更改,它可能只是簡單地返回對原始字符串的引用。 – Sinatr

+0

順便說一句。如果您從MSDN鏈接中刪除「pl-pl /',則每個人都將以他們的(UI)語言獲得該文章的版本。 - (或默認爲en-US) – Corak

回答

4

String.ToString()返回的引用,相同的字符串:

public override String ToString() { 
    Contract.Ensures(Contract.Result<String>() != null); 
    Contract.EndContractBlock(); 
    return this; 
} 

並在運行時創建的字符串可以被拘禁。從MSDN article引用您簡稱:

運行時並不能保證在運行時創建的字符串拘留

實習是一項昂貴的操作,通常是太貴了在運行時做到這一點。如果你想確保你的字符串是被攔截的,你可以使用public static String Intern(String str)方法。

+0

謝謝。 「在運行時創建的字符串不能被實施。」是來自MSDN的確切引用,所以他們自相矛盾一點。無論如何,我應該在提問之前閱讀全文。 – kuszi

+1

@ kuszi MSDN代碼示例的註釋:)... [文章](https://msdn.microsoft.com/library/dd183759.aspx)中的文本說:「...運行時*不保證*字符串在運行時創建的實例也不會保證不同的程序集中的兩個相等的常量字符串被實現。「 –

+1

@kuszi可能在代碼中發表評論意思是說「編譯器/運行時不能自動實習級聯的結果,因爲它需要明確的用戶請求」而不是「不能這樣做」。 –