93人参与 • 2026-05-08 • Asp.net
c# 中 string 是不可变(只读)引用类型:一旦字符串在内存中创建,就永远不能被修改,任何 “修改” 操作都不会改动原字符串,而是新建一个字符串。
string s = "abc"; s.toupper(); console.writeline(s); // 还是 abc,原字符串没变
toupper() 没有改原 s,而是返回了一个全新字符串对象。
再看拼接:
string a = "123"; a += "456";
底层:
"123""123456" 新字符串a 引用指向新对象,旧对象等待 gc频繁拼接字符串(循环里 +=)会不断生成新字符串、大量创建临时对象、触发 gc。解决方案:stringbuilderstringbuilder 是可变的,内部维护字符缓冲区,原地修改,不频繁新建对象。
clr 维护的一个全局字符串缓存池,目的:复用相同内容的字符串实例,节约内存、减少重复分配。
核心规则:内容相同的字符串,在驻留池中只存一份,多个引用指向同一个内存地址。
string.intern())原理
代码里双引号直接写的字面量字符串,编译时 clr 会:
示例证明地址相同
string s1 = "hello"; string s2 = "hello"; // 值相等 console.writeline(s1 == s2); // 引用地址也相等 同一个对象 console.writeline(object.referenceequals(s1, s2));
输出都是 true👉 s1、s2 指向堆上同一个字符串实例。
不进入驻留池的情况
运行时动态拼接、new 出来的字符串,默认不驻留:
string s1 = "hello";
string s2 = "hel" + "lo"; // 编译器优化,还是字面量,会驻留
string s3 = new string("hello".tochararray());
console.writeline(object.referenceequals(s1, s3)); // falses3 是运行时构造,不在驻留池,是新对象。
用法
string s3 = new string("hello".tochararray());
string internstr = string.intern(s3);
// 现在和 s1 指向同一个驻留池实例
console.writeline(object.referenceequals(s1, internstr)); // trueintern 原理
适用场景:大量重复动态字符串(如日志、解析文本),手动驻留省内存。
string.intern 手动入池,复用实例省内存stringbuilder,避免大量生成新字符串以上就是一文详解c#字符串不可变性和字符串驻留池的详细内容,更多关于c#字符串不可变性和驻留池的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论