2

基本上在这里我想用一个例子来说明字符串是不可变的,所以我举了下面的例子,我知道 GetHashCode() 不返回地址但是我如何区分两个变量引用不同的内存位置?

在下面的代码中,我想要一个字符串变量的地址

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

但在 String Builder 的情况下 GetHashCode() 返回相同的值

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

3 回答 3

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

也许这更接近您正在寻找的东西?

于 2013-07-03T17:56:03.413 回答
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==运算符默认为 using 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
于 2013-07-03T17:55:44.730 回答
0

Object.ReferenceEquals(a, b)返回falseiffa并且b是对不同对象的引用(因此是不同的地址)。

字符串生成器的哈希码可能是从字符串生成器的地址构造的,而不是从它存储的字符串值构造的。

s + "hello"另一方面,创建一个具有与 不同哈希码的新对象s

于 2013-07-03T17:56:33.090 回答