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个变量s
和d
指的是内存中的同一个对象。
s = "elvis presley";
在声明的右边部分,新对象被分配并用"elvis presley"
初始化并分配给s
。 所以现在s
指的是另一个对象。 虽然我们没有更改d
参考值 – 但它仍然像最初那样继续引用"lana del rey"
。
现在真实的比喻:
有两个人( A
和B
)用手指指向远处的建筑物。 它们彼此独立,甚至看不到另一个指向的东西。 然后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)