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

时间:2014-01-15 20:49:35

标签: c# reference-type

我对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是值类型。如何使用字符串演示相同的引用类型行为?

提前致谢。

6 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:5)

没有与可变性相关

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:你可能会混淆的是指针和引用背后的概念。不确定在这里解释它是否有意义,因为你可能会更加困惑。但现在至少你可以谷歌搜索相应的关键字。

答案 2 :(得分:3)

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

答案 3 :(得分:2)

让我们逐行查看您的代码

string s = "lana del rey";

使用此行,您创建了lana del rey

引用的字符串对象s
string d = s;

使用此行,您创建了一个名为d的引用,该引用引用了内存中的相同对象(在本例中为lana del reys < / p>

s = "elvis presley";

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

Console.Writeline(d);

由于d仍引用lana del rey,因此会打印lana del rey

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

从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)