如果a
和b
都引用同一个对象,那么当我们在 part3中更改a
的值时,为什么b
的值不会发生变化< / em>的。如果我假设(在 part3 中)b
在我传递一个新的文字字符串时被解除引用,为什么它也不会在 part2中取消引用当我通过"foo"
litaral字符串(ReferenceEquals
返回true
)时。
//part1
string a = "foo";
string b = a;
System.Console.WriteLine("\na = {0}\nb = {1}", a, b); //a=foo b=foo
System.Console.WriteLine("a == b : {0}", a == b);//True
System.Console.WriteLine("ReferenceEquals(a, b): {0}", ReferenceEquals(a, b));//True
//part2
b = "foo";
System.Console.WriteLine("\na = {0}\nb = {1}", a, b);//a=foo b=foo
System.Console.WriteLine("a == b : {0}", a == b);//True
System.Console.WriteLine("ReferenceEquals(a, b): {0}", ReferenceEquals(a, b));//True
//part3
b = "bar";
System.Console.WriteLine("\na = {0}\nb = {1}", a, b);//a=foo b=bar
System.Console.WriteLine("a == b : {0}", a == b);//False
System.Console.WriteLine("ReferenceEquals(a, b): {0}", ReferenceEquals(a, b));//False
答案 0 :(得分:7)
a
和b
都指向同一个对象
但是,您正在更改b
,而不是对象。
String
个对象是不可变的,无法更改。
当您撰写b = "foo"
时,您正在更改b
以引用其他String
个实例。
但是,字符串文字为interned,因此编写"foo"
将始终提供相同的String
实例。
通过调用String.Copy
,您可以获得两个具有相同值的String
个实例:
string a = "foo";
string b = "foo";
Console.WriteLine(ReferenceEquals(a, b)); //True
b = String.Copy("foo");
Console.WriteLine(ReferenceEquals(a, b)); //False
答案 1 :(得分:3)
如果您更改某些内容,例如a = "newstring";
,则表示'a'指向新引用。
字符串不可变 - &gt;你无法更改字符串本身(a[0] = 'b';
)。
在第2部分中,当您指定先前使用的某个常量时,将使用对旧旧的引用。这被称为“实习”。
如果你做了b = "fo" + "o";
,那么引用就不一样了(在这个例子中他们会这样做,因为编译器对此进行了优化,但是如果字符串是以不同于直接使用的方式创建的,则引用是相同的)。 / p>
var a = "foo";
var b = "fo";
b = b + "o";
// in this point, the references AREN'T equal.
b = string.Intern(b);
// in this point, the references ARE equal.
答案 2 :(得分:1)
“字符串是不可变的 - 在创建对象后,不能更改字符串对象的内容,尽管语法使它看起来好像你可以这样做。”
答案 3 :(得分:0)
a和b都是第1部分中对同一事物的引用
在第2部分中,引用保持不变,因为编译器已提前解决了您只是重用相同的字符串文字(一点内存优化),并且因为字符串是不可变的,所以它知道进行优化是安全的。
在第3部分中,您只是将引用更改为b。 a仍然像以前一样提到“foo”。
答案 4 :(得分:0)
a和b都指向同一个对象。如果您将'a'分配给'b'然后更改'b'的值
,如何更改?