如果字符串是不可变的,这是否意味着值重新分配会创建一个具有相同名称的新字符串对象?

ror*_*ory 0 c# string object immutability

例如:

string test = "abcde"; // "abcde"
test = test.Substring(1); //"bcde"
Run Code Online (Sandbox Code Playgroud)

这是否意味着test第二行与第一行不是同一个对象test?即编译器创建了一个新的字符串对象实例并称之为'test',第一个'test'被发送到垃圾收集器?

如果是这样,这是我需要关注的吗?

谢谢

Eri*_*ert 13

Schabse的答案当然是正确的; 然而,我会进一步澄清你的想法.

这是否意味着第二行的测试与第一行的测试不同?

是.test变量的名称.(请记住,并非所有变量都有名称,但这个变量具有名称.)变量存储.甲参考是一种.首先,将特定字符串的引用分配给test.然后在下一行分配不同的引用.

编译器创建了一个新的字符串对象实例,并将其命名为"test",并将第一个"test"发送到垃圾收集器?

编译器没有做这样的事情.甲编译器是其转化一种语言编写成其他语言编写的程序的程序的装置.C#编译器将C#转换为包含MSIL代码和元数据的可移植可执行文件.该代码指示CLR创建字符串.

CLR在运行这个程序片段时,创建了一个新的字符串对象实例并称之为'test'

不,CLR创建了一个新实例,string并将该实例的引用分配给名为的变量test.该实例是不是有一个名字的事情.存储对实例的引用变量是具有名称的事物.不要混淆两个!如果我有一本名为" 我的地址簿"的地址簿,地址簿中包含地址"Barry Obama,1600 Pennsylvania Avenue,Washington DC",那个地址的房子名称仍然是白宫,而不是我的地址簿.

CLR创建了一个新的字符串对象实例,为其分配一个引用以进行测试,该引用已经包含一个引用.由于先前引用的对象现在不再由任何根引用,因此垃圾收集器立即释放它.

首先,不需要释放对文字字符串的引用.其次,假设抛出的引用不是文字,垃圾收集器按照自己的计划运行,当它运行时.没有该字符串的要求不断被释放.当然,当进程终止时 - 如果它终止 - 那么将释放所有进程内存.

现在我们可以解决您的原始问题:

如果字符串是不可变的,这是否意味着值重新分配会创建一个具有相同名称的新字符串对象?

问题是不连贯的,因为(1)引用语义完全独立于字符串是否是不可变的,(2)对象没有名称,变量有名称.你能改一下你的问题吗?

这是我需要关注的吗?

如果你想成为一名C#程序员,那么你应该关注C#的基本原理.


SLa*_*aks 8

这正是发生的事情,除了字符串文字被实习并且永远不会是GC.

此外,对象没有名称; 相反,它创建一个新String实例并使您的变量引用它.

  • @rory:不; 你可能没有大量的字符串**文字**. (2认同)