2012-02-02 40 views
7

爲什麼在這種情況下ReferenceEquals對象的方法行爲有所不同?ReferenceEquals與字符串錯誤工作

string a= "fg"; 
string b= "fg"; 
Console.WriteLine(object.ReferenceEquals(a, b)); 

所以在這種情況下得到的結果是true。在情況下,它會比較我的字符串和非引用的值。但是,當我寫的東西,如:

StringBuilder c = new StringBuilder("fg"); 
string d = c.ToString(); 
Console.WriteLine(object.ReferenceEquals(a, d)); 

在這種情況下,它工作正常,結果是false,因爲我比較對象的引用。

+1

即使查克諾里斯在SO上。哇! – RBT 2016-10-14 10:23:15

回答

13

第一個示例具有編譯時間常量"fg",它由兩個變量引用。由於這是一個編譯時間常量,因此這兩個變量引用一個對象。參考文獻是平等的。

閱讀字符串國際的主題了解更多關於此行爲的信息。作爲初學者,請考慮:

例如,如果將相同的文字字符串分配給多個變量,運行時將檢索對來自intern池的文字字符串的相同引用,並將其分配給每個變量。

http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

在第二個例子中,只有一個是編譯時間常數,另一種是某些操作的結果。 ad不引用相同的對象,因此您從ReferenceEquals得到錯誤結果。

+0

@亨克,雖然我承認我對這個概念並不完全熟悉,但我不確定你要去哪裏摺疊。我的讀法很簡單,就是摺疊是一個字面表達式,例如''f「+」g「'將被編譯器轉換爲'」fg「'。但是,在代碼中'string a =「fg」;字符串b =「fg」;',你期望在IL中看到IL_0000:ldstr「fg」/ IL_0005:stloc.0/IL_0006:ldstr「fg」/ IL_000B:stloc.1' – 2012-02-02 15:11:50

+0

事實上,如果你也有'string c =「f」+「g」',發出相同的指令來加載「fg」。對於我自己的教育,a和b的摺疊在哪裏? – 2012-02-02 15:12:54

2

它在兩種情況下都表現正確。

原因ab是相同的字符串對象是因爲編譯器已經注意到你指定的字符串相同的兩倍,並重復使用相同的字符串對象來初始化ab

這通常會發生在您的應用程序中的每個字符串常量。

0

根據這一post它與一些所謂的實習做。 a和b在你的情況下指向同一個實例的兩個變量,這就是爲什麼ReferenceEquals返回true。