为何内容相同的两个字符串变量会指向同一引用?
为什么str1和str3的ReferenceEquals返回True?
先看你给出的代码:
var str1 = "C#"; var str2 = "F#"; var str3 = "C#"; Console.WriteLine(Object.ReferenceEquals(str1, str2)); // False Console.WriteLine(Object.ReferenceEquals(str1, str3)); // True <-- Why?
答案是.NET的**字符串驻留(String Interning)**机制在起作用:
- 字符串的不可变性是基础:因为字符串一旦创建就不能修改,CLR可以放心复用相同内容的字符串实例,不用担心后续修改会影响其他引用。
- 对于编译期就能确定内容的字符串字面量(比如代码里的"C#"),CLR会自动将其加入字符串驻留池——这是一个专门存储唯一字符串实例的内存区域。
- 当你声明
str3 = "C#"时,CLR会先检查驻留池里有没有内容完全匹配的字符串,发现已经有str1指向的那个"C#"实例,就直接让str3引用它,不会再新建对象。 - 而str2的内容是"F#",驻留池里没有对应的实例,所以会创建新的字符串对象,因此和str1的引用不相等,
ReferenceEquals返回False。
额外说明:运行时动态生成的字符串(比如用拼接、String.Format生成的)默认不会自动进入驻留池,如果你想让它们也被复用,可以手动调用String.Intern()方法将其加入驻留池。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

