字符串引用

本文关键字:引用 字符串 | 更新日期: 2023-09-27 18:00:08

如果ab都是对同一对象的引用,当我们在第3部分中更改b的值时,为什么a的值不更改。如果我假设(如在第3部分中)当我给b传递一个新的文字字符串时,它被取消引用,为什么当我传递"foo"文字字符串时(ReferenceEquals返回true),它不在第2部分中也取消引用呢。

//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

字符串引用

ab都引用同一个对象
但是,您更改的是b,而不是对象。

String对象是不可变的,不能更改。

当您编写b = "foo"时,您正在将b更改为引用不同的String实例。


但是,字符串文字是内部的,因此编写"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

如果您更改某些内容,如a = "newstring";,则意味着"a"指向新引用

字符串是不可变的->您不能更改字符串本身(a[0] = 'b';)。

在第2部分中,当您分配以前使用的某个常量时,将使用对旧常量的引用。这叫做"实习"。

如果使用b = "fo" + "o";,则引用将不相等(在本例中,它们会相等,因为编译器对此进行了优化,但如果以其他方式创建字符串而不是直接使用,则引用是相同的)。

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.

"字符串是不可变的——在创建对象后,字符串对象的内容不能更改,尽管语法使其看起来像可以这样做。"

请参阅http://msdn.microsoft.com/en-us/library/362314fe.aspx

a和b都引用了第1部分中的相同内容

在第2部分中,引用保持不变,因为编译器已经提前计算出您只是重复使用相同的字符串文字(一点内存优化),并且因为字符串是不可变的,它知道进行优化是安全的。

在第3部分中,您仅将引用更改为b。a仍然像以前一样引用"foo"。

a和b都引用同一个对象。如果将"a"分配给"b",然后更改"b"的值,则如何更改