在学习.net编程时,你一定有听到过这样的说法,System.String类是不可变字符串,也就是说你不能修改一个字符串的值。
比如以下这段代码
string s = "hello";
s = "world";
你并不是把s的值修改为world,而是生成了一个新的包含"world"的字符串,然后令s这个字符串的引用指向新的字符串,而原来的那个字符串就被抛弃掉了。
也正是基于String类的不可修改性,CLR采用了String Interning的技术来共享相同的字符串,以达到减少内存使用的目的。比如以下这段代码
string s1 = "hello";
string s2 = "hello";
if (Object.ReferenceEquals(s1, s2))
Console.WriteLine("They are same");
s1和s2其实指向相同的字符串。
那么是不是我们真的没有办法改变一个string的值呢?当然不是,在C++/CLI中,我们可以使用一些特殊的手段来达到我们的目的!
String^ s1 = "hello";
String^ s2 = "hello";
interior_ptr<Char> p = const_cast<interior_ptr<Char> >(PtrToStringChars(s1));
for(; *p; *p++='a');
Console::WriteLine("{0} and {1}",s1,s2);
比如以下这段代码


你并不是把s的值修改为world,而是生成了一个新的包含"world"的字符串,然后令s这个字符串的引用指向新的字符串,而原来的那个字符串就被抛弃掉了。
也正是基于String类的不可修改性,CLR采用了String Interning的技术来共享相同的字符串,以达到减少内存使用的目的。比如以下这段代码





s1和s2其实指向相同的字符串。
那么是不是我们真的没有办法改变一个string的值呢?当然不是,在C++/CLI中,我们可以使用一些特殊的手段来达到我们的目的!








PtrToStringChars(String^)是一个定义在vcclr.h头文件中的一个helper function,它返回一个类型为interior_ptr<const Char>的内部指针,指向String实例内部所包含的字符串,之所以返回类型是interior_ptr<const Char>而不是interior_ptr<Char>是因为不希望我们改变String实例内的字符串,不过既然我们执意要这么做,那么就让我们用一个const_cast<T>来把这个const搞掉!
运行以上代码你会发现,s2现在的内容已经是aaaaa,而不是hello了。
当然,以上例子只是说明存在修改string实例的内容的可能,并不是鼓励大家这么做。虽然直接访问string实例内部的字符串,可能会带来一些性能上的好处。但是由于String Interning的存在,修改String实例内部的字符串是相当危险的行为,比如上面的那个例子中,你会发现,s1的输出也变成aaaaa了!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端