2013-07-03 24 views
2

基本上我想顯示字符串是不可變的一個例子,所以我拿下面的例子,我知道GetHashCode()不會返回地址,但我怎麼能區分這兩個變量引用不同的內存位置?如何獲取參考變量的地址?

在下面的代碼,我希望有一個字符串變量的地址

 string s = "hello"; 
     Console.WriteLine(s.GetHashCode()); 
     s = s + "User"; 
     Console.WriteLine(s.GetHashCode()); 

但在字符串構建的情況下GetHashCode()方法返回相同的值

 StringBuilder sb = new StringBuilder(); 
     sb.Append("hi"); 
     Console.WriteLine(sb.GetHashCode()); 
     sb.Append("hello"); 
     Console.WriteLine(sb.GetHashCode()); 

回答

8

只要使用兩個不同的變量和object.ReferenceEquals代替:

string x = "hello"; 
string y = x + "User"; 
Console.WriteLine(ReferenceEquals(x, y)); 

誠然只是打印xy在這一點上會表明他們」重新不​​同...作爲一個輕微的替代:

string s = "hello"; 
string original = s; 
Console.WriteLine(ReferenceEquals(s, original)); // True 
s = s + "User"; 
Console.WriteLine(ReferenceEquals(s, original)); // False 

也許這更接近你所尋找的g爲?

+0

@Skeet不應該在每種情況下都是Object.ReferenceEquals(...)'? – feralin

+0

@feralin不,不應該... –

+0

@newStackExchangeInstance請詳細說明。 – feralin

7

爲您給出的例子,你不實際上需要知道地址 - 你只想知道兩個對象的地址是否相同。

string s1 = "hi"; 
string s2 = s1; 
Console.WriteLine(object.ReferenceEquals(s1, s2)); // True 
s2 = s2 + " world"; 
Console.WriteLine(object.ReferenceEquals(s1, s2)); // False 

有趣的一面注意object==運營商默認使用object.ReferenceEquals(),但由於string在C#中覆蓋==操作,檢查兩個字符串之間的平等將基於字符串是否相等。爲了進一步複雜化,編譯器在編譯時「實時」處理任何可以告訴的常量字符串。這些行爲的結合,讓你有一些很奇怪的行爲:

string s1 = "john"; 
object s2 = "john"; 
string s3 = new StringBuilder(s1).ToString(); 
Console.WriteLine(s1 == s2); // True 
Console.WriteLine(s2 == s1); // True 
Console.WriteLine(s1 == s3); // True 
Console.WriteLine(s3 == s1); // True 
Console.WriteLine(s2 == s3); // False 
Console.WriteLine(s3 == s2); // False 
+0

達尼特,打我吧:) – feralin

+1

@feralin:你在一個很好的公司。我也設法擊敗了Skeet! – StriplingWarrior

0

Object.ReferenceEquals(a, b)返回false iff ab是對不同對象(以及不同地址)的引用。

字符串生成器的哈希碼大概是從字符串生成器的地址構建的,而不是它存儲的字符串值。

s + "hello"另一方面創建具有與s不同的哈希碼的新對象。