字符串在c#中是如何工作的?
我知道字符串是不可变的,一旦创建,我们就无法更改它。我读到,如果我们创建一个新的字符串对象,给它赋值,然后在内部给同一个字符串对象赋值,实际上会创建另一个对象,并给它赋值。假设我有:字符串在c#中是如何工作的?,c#,string,heap-memory,stack-memory,C#,String,Heap Memory,Stack Memory,我知道字符串是不可变的,一旦创建,我们就无法更改它。我读到,如果我们创建一个新的字符串对象,给它赋值,然后在内部给同一个字符串对象赋值,实际上会创建另一个对象,并给它赋值。假设我有: string str = "dog"; str = "cat"; 如果我写Console.WriteLine(str)返回cat。 那么内部有两个对象?但是他们有相同的名字吗?它是如何工作的?我对谷歌做了一些研究,但我还没有找到足够让我信服的东西,所以我可以澄清我的想法。 我知道字符
string str = "dog";
str = "cat";
如果我写Console.WriteLine(str)代码>返回cat
。
那么内部有两个对象?但是他们有相同的名字吗?它是如何工作的?我对谷歌做了一些研究,但我还没有找到足够让我信服的东西,所以我可以澄清我的想法。
我知道字符串是引用类型,所以堆栈中有一个对象引用堆中的一个值,在这种情况下会发生什么?(参见上面的代码)
我上传了一张图片,如果我对堆栈和堆的概念有错误,请向我道歉,这就是我问这个问题的原因。
图片是否反映了第一行代码(string str=“dog”
)中发生的情况?那么在第二行代码中会发生什么呢??堆中的dog
值是否更改?然后在堆栈中创建一个引用它的新对象?那么之前存在的物体会发生什么?他们有相同的名字吗?
我很抱歉问了这么多问题,但我认为正确理解这一点以及了解幕后发生了什么是非常重要的…是的,有两个对象。不,他们的名字不一样。尽量不要把变量看作对象本身的“名称”——它更像是对象在内存中位置的临时名称。(将变量视为对象的“名称”有些误导的原因是,可以有多个变量引用同一个对象;对象本身并不是有多个“名称”,也不是有多个对象——这只是存储引用的方式)
字符串str最初引用字符串dog。将“cat”赋值给“str”后,变量现在引用字符串cat
这两个字符串仍然存在于内存中(至少暂时存在),但“dog”字符串不再可访问,因为您没有对它的引用(因此不再“知道”它的位置)。您不知道它们在内存中会存在多长时间,因为垃圾收集器可以随时从内存中删除“dog”字符串,因为不再有对它的任何引用
顺便说一句,堆栈上的值与堆上的对象的引用是正确的-这是一个很好的区别。很接近。您的图片准确地表示第一行代码中发生的情况。然而,事情与您在第二行代码中描述的有点不同
对于行str=“cat”代码>,则在堆中创建第二个字符串对象,并将str
变量更改为引用该新对象。剩下的str
指向“cat”
,堆上还有一个孤儿“dog”
对象,没有对它的引用
垃圾收集器可能会清理“dog”
对象,因为没有对它的引用。查看或。
基本上,公共语言运行库(CLR)维护一个[唯一]字符串值的表,每当您在代码中操作字符串时,CLR都会检查这个intern表,以查看您尝试创建的新值是否已经在其中。如果是,它只是重新分配您正在修改的变量,以指向实习生池中的该条目。如果不是,则将该值添加到池中并返回该新引用。池中不再由变量引用的旧值将被垃圾回收 当您将str
赋值给“dog”时,它会按照上面在内存中描述的那样执行:引用变量str
现在“指向”刚刚实例化的字符串的位置
str => MEMORY LOCATION "1": "dog"
MEMORY LOCATION "2":
MEMORY LOCATION "3":
当str
被重新分配给新字符串“cat”时,它也会在内存中创建,现在str
被调整,使其指向新位置的“cat”
MEMORY LOCATION "1": "dog"
str => MEMORY LOCATION "2": "cat"
MEMORY LOCATION "3":
“狗”怎么了?现在它实际上是不可访问的,因为我们不再有对其位置的引用(在内存、堆中,术语在这种情况下是可互换的)。稍后,当垃圾收集器检查内存进行清理时,它会意识到没有引用“dog”的内容,它会根据需要标记内存以进行删除和替换。我很难选择答案,因为您所有的答案都是非常描述性的,我现在已经澄清了这一点,谢谢!!!这个答案完全错了。字符串仅在编译时隐式插入。在运行时,只有当代码通过调用string.Intern()
方法显式请求字符串时,字符串才会被插入。此外,一旦进入实习生池,string
对象就永远不会被垃圾收集。他们无限期地留在那里。实习生池不是缓存,它主要是一个放置编译代码时发现的字符串文本的地方。