Albaharis 的“C# 4.0 IN A NUTSHELL”第 4 版书在第 249 页上指出:“......调用 object.ReferenceEquals 保证正常的引用相等性。”
所以,我决定测试一下。
首先我尝试了这样的值类型。
int aa1 = 5;
int aa2 = aa1;
MessageBox.Show("object.ReferenceEquals(aa1,aa2) is: " + object.ReferenceEquals(aa1, aa2));
正如我所料,结果是假的:object.ReferenceEquals(aa1, aa2) is: False
生活很好。然后我尝试了一个像这样的可变引用类型。
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
System.Text.StringBuilder sblr2 = sblr1;
MessageBox.Show("object.ReferenceEquals(sblr1,sblr2) is: " + object.ReferenceEquals(sblr1, sblr2));
正如我所料,结果是真的 object.ReferenceEquals(sblr1, sblr2) is: True
生活还是不错的。然后我想,既然它是一种可变引用类型,那么如果我将一个变量更改为 null,那么两者都应该为 null。所以我尝试了以下方法。
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
System.Text.StringBuilder sblr2 = sblr1;
sblr1 = null;
MessageBox.Show("object.ReferenceEquals(sblr1,sblr2) is: " + object.ReferenceEquals(sblr1, sblr2));
我希望它们都为空。但我得到的结果是 False: object.ReferenceEquals(sblr1, sblr2) is: False
现在生活不是那么好。我认为如果它覆盖了 sblr1 的内存位置,那么它也会覆盖 sblr2 的内存位置。
然后我想也许他们指向两个不同的空值,所以我尝试了这个:
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
System.Text.StringBuilder sblr2 = sblr1;
sblr2 = null;
MessageBox.Show("sblr1 == " + sblr1 + " and sblr2 == " + sblr2);
但在这里,只有一个像这样指向一个空值。sblr1 == aaa 和 sblr2 ==
只有一个是空的。
它显示了我对字符串对象等不可变引用类型所期望的行为。使用字符串对象,我可以执行以下操作:
string aa1 = "aaX";
string aa2 = "aaX";
MessageBox.Show("object.ReferenceEquals(aa1,aa2) is: " + object.ReferenceEquals(aa1, aa2));
他们都会引用同样的东西。object.ReferenceEquals(aa1, aa2) 是:True 因为“aaX”只被写入程序集一次。
但如果我这样做:
string aa1 = "aaX";
string aa2 = "aaX";
aa1 = null;
MessageBox.Show("After aa1 is null(" + aa1 + "), then aa2 is: " + aa2);
然后他们指向不同的东西是这样的: aa1 为 null() 之后,然后 aa2 为:aaX
那是因为字符串对象是不可变的。内存位置不会被覆盖。相反,该变量指向堆内存中存在新值的不同位置。在上面的示例中将 aa1 更改为 null 意味着 aa1 将指向堆内存上的不同位置。
那么为什么可变引用类型的行为与不可变引用类型相同呢?
编辑下午 4:03 和 4:08
我最近试过这个:
System.Text.StringBuilder sblr1 = new System.Text.StringBuilder();
sblr1.Append("aaa");
// sblr1 and sblr2 should now both point to the same location on the Heap that has "aaa".
System.Text.StringBuilder sblr2 = sblr1;
System.Text.StringBuilder sblr3 = new System.Text.StringBuilder();
sblr3.Append("bbb");
sblr1 = sblr3;
MessageBox.Show("sblr1 == " + sblr1 + " and sblr2 == " + sblr2 + " and sblr3 == " + sblr3);
这给了我: sblr1 == bbb 和 sblr2 == aaa 和 sblr3 == bbb
这更像是我所期待的结果。多亏了评论,我现在看到,我下意识地期望 null 充当内存位置。