两个具有相同值的字符串在内存中是如何存储的?

5
string first="Example";
string second="Example";

这两个字符串具有相同的哈希码,并且两个引用也是相同的。我的问题是:这些字符串变量在内存位置上是否只有一份数据副本?

string third="Example";
static string fourth="Example";
const string fifth="Example";

上述两个集合之间有什么区别吗?

2
在这种情况下,所有变量引用相同的字符串对象,因为字面字符串被添加到字符串池中。 - Tim Schmelter
1
除了Tim之外,当使用new string("Example")时,您将创建一个新引用指向新实例。 - MakePeaceGreatAgain
1个回答

5
在这个特定的例子中,所有的字符串都是不同的引用,但有相同的值,指向单个字符串对象。这是因为ldstr IL指令对字面字符串进行内部处理,并重用它们,而不是每次ldstr执行时分配内存。
你可以通过ReferenceEquals(first, second)等方法来检查这一点。
请注意,const变量则稍微有些不同,因为它会在调用处转换为字面ldstr,并且内部处理共享情况取决于程序集边界。
但要注意:并非所有的"Example"都必须是相同的引用。大多数其他获取字符串的机制(例如处理输入数据)不会查看内部处理共享情况,而只会构建一个新的字符串。

谢谢指出!我需要阅读一下这个主题^^ - Master Azazel
谢谢您的回答,但我还有一个问题要问您。在上面的代码片段中,每个都有单独的引用,即使我们将它们 intern,它们之间有什么区别? - Mr.Throg
@VenkatLokeswar 实际上,test2test3是同一个引用 - 尽管test.ToString()返回的中间字符串是分开的;当这个字符串通过string.Intern时,你会得到与ldstr获得的相同的内部版本。首先,test不是一个string,因此不能是同一个引用。 - Marc Gravell
你好,Marc Gravell, 我们能否对字符串使用运算符重载? - Mr.Throg
@VenkatLokeswar 在什么情况下?对于 string,已经定义了一些运算符;由于 string 类型是内置的,因此您无法向其添加运算符 - 但是您拥有的其他类型可以声明涉及字符串的转换、相等性等运算符。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接