C#字符串引用类型作为副本传递?

我怀疑与C#“String”引用类型有关。

以下代码:

string s = "lana del rey" string d = s; s = "elvis presley"; Console.Writeline(d); 

为什么输出不是“elvis presley”? 如果d指向s的相同内存位置?

你能解释一下吗?

我最初问题的更详细解释:

你的所有答案都非常有用。 这个常见的代码示例经常用来解释值类型和引用类型之间的区别,这个问题来找我:

 class Rectangle { public double Length { get; set; } } struct Point { public double X, Y; } Point p1 = new Point(); p1.X = 10; p1.Y = 20; Point p2 = p1; p2.X = 100; Console.WriteLine(“p1.X = {0}”, p1.X); Rectangle rect1 = new Rectangle { Length = 10.0, Width = 20.0 }; Rectangle rect2 = rect1; rect2.Length = 100.0; Console.WriteLine(“rect1.Length = {0}”,rect1.Length); 

在这种情况下,第二个Console.WriteLine语句将输出:“rect1.Length = 100”

在这种情况下,类是引用类型,struct是值类型。 如何使用字符串演示相同的引用类型行为?

提前致谢。

它与可变性无关

 string s = "lana del rey" string d = s; 

这里有2个变量sd指的是内存中的同一个对象。

 s = "elvis presley"; 

在声明的右边部分,新对象被分配并用"elvis presley"初始化并分配给s 。 所以现在s指的是另一个对象。 虽然我们没有更改d参考值 – 但它仍然像最初那样继续引用"lana del rey"

现在真实的比喻:

有两个人( AB )用手指指向远处的建筑物。 它们彼此独立,甚至看不到另一个指向的东西。 然后A决定开始指向另一个建筑物 。 只要它们没有相互连接 – 现在A指向另一个建筑物, B继续指向原始建筑物(因为没有人要求他们停止这样做)

PS:你可能会混淆的是指针和参考背后的概念。 不确定在这里解释它是否有意义,因为你可能会更加困惑。 但现在至少你可能会谷歌搜索相应的关键字。

C#中的字符串是不可变的 ; 这意味着他们无法改变。 当你说s = "elvis presley"你正在创建一个新字符串并将其引用分配给s ; 这不会影响保存到d的引用,它仍然指向原始字符串。

字符串是不可变的。 s = "elvis presley"实际上是创建一个新string并将其引用给变量s 。 变量d仍引用第一个string “lana del rey”。

让我们逐行查看您的代码

 string s = "lana del rey"; 

使用此行,您创建了一个由s引用的字符串对象lana del rey

 string d = s; 

使用这一行,你创建了一个名为d引用,它引用了内存中的同一个对象 (在本例中是lana del rey

 s = "elvis presley"; 

使用此行,您创建了一个新的字符串对象elvis presley并由s引用(s不再引用lana del rey

 Console.Writeline(d); 

由于d仍然引用lana del rey ,它会打印lana del rey

字符串的处理方式与常规引用类型不同,这基本上是编译器的作用:

 string s = new String("lana del rey"); string d = new String(s); s = new String("elvis presley"); Console.Writeline(d); 

该点是“字符串引用”指向s的字符串VALUE。 任何时候创建一个NEW字符串并引用它是一个新字符串,并且对原始值的任何“引用”仍然完好无损。

从Microsoft .NET Framework 2.0应用程序开发基础70 536书:

“因为引用类型代表数据的地址而不是数据本身,所以将一个引用变量分配给另一个引用变量不会复制数据。相反,将引用变量分配给另一个实例只会创建引用的第二个副本,它指的是堆上的内存位置与原始变量相同。“

然后我想:

 string s = "lana del rey"; // (creates a reference to the memory location X) string d = s; // (creates a copy of the reference to the same memory location X) d = "elvis presley"; // (creates a new reference to the new memory location Y)