C# 特殊的string类型详解
作者:PowerDK 发布时间:2022-02-10 14:11:59
1.前言
string是属于引用类型的,这个大家都知道吧?但是平常在使用的过程中,发现它还是拥有一些值类型的特征的,这到底是为什么呢?
原因就是.Net考虑到假如大量的操作string对象的时候,大量对引用对象进行操作的时候,性能肯定不如值类型来的爽快。.Net为了提高这个性能,提供了一个专门的解决方案:字符串驻留池!
2.正文
先让我们来看一段代码:
string str1 = "aa";
string str2 = "a" + "a";
Console.WriteLine(ReferenceEquals(str1, str2)); //print:true
这str1跟str2的内存指向地址居然是一模一样的!
原因是.Net在CLR内部维护了一个Hash表(其实就是前文说的字符串驻留池),key为字符串内容,值就是所指向的托管堆的地址;当初始化创建了一个新的字符串的时候,.Net就会去这个Hash表中搜索是否有相同的值,如果key相同,就会把已经存在的字符串的地址值赋给新创建的字符串,如果不存在则重新分配地址,这就是为什么上面这个代码的内存为true。
再让我们来看另外一段代码:
string str3 = "ab";
string str4 = "a";
str4 += "b";
Console.WriteLine(ReferenceEquals(str3, str4));//print :false
之所以出现了false,请注意上一栏的关键字“初始化创建”,当字符串是动态创建的时候,.Net并不会去Hash表中搜索是否有创建,而是直接创建;
假如想对上面的代码优化一下并且对性能有更(xian)高(de)追(dan)求(teng),我们可以手动将这个字符串加入到字符串驻留池中进行对比
string str3 = "ab";
string str4 = "a";
str4 += "b";
str4 = string.Intern(str4);//Intern:它会去字符串驻留池中搜索,假如找寻到的话则返回对应的地址
Console.WriteLine(ReferenceEquals(str3, str4));//print :true
3.总结
最后对string下点结论:
1.string在clr中不是用newobj指令创建,而是用ldstr指令创建!而且string拥有值类型的特征,但是在内存上是引用类型,存在托管堆上面;
2.string是sealed修饰的,所以不能被子类集成;
3.当创建内容相同的时候,string是指向同一地址的,而且每次操作string都会生成新的地址(string的恒定性);
4.对于大量拼接的话还是使用StringBuilder,它是动态的不像string是恒定的,但就是创建StringBuilder代价比较大,所以小拼接用string在性能上可能还更好!
来源:http://www.cnblogs.com/powerdk/p/6391024.html


猜你喜欢
- 1、文件上传1.1 后端部分1.1.1 引入Apache Commons FIleUpload组件依赖<!--文件上传与下载相关的依赖
- 本文实例为大家分享了DigitalClock实现商品倒计时的具体代码,供大家参考,具体内容如下自定义DigitalClock控件:packa
- 我最近上班又遇到一个小难题了,就是如题所述:ViewPager预加载的问题。相信用过ViewPager的人大抵都有遇到过这种情况,网上的解决
- 先来看看效果图如何使用示例代码PromptViewHelper pvHelper = new PromptViewHelper(mActiv
- 前言本来是打算用C#爬取天气网站上的信息,然后用正则表达过滤有用信息的,但是很淦,正则表达式太难了。无意间找到添加web引用的方式来获取天气
- 这两天遇到一个服务假死的问题,具体现象就是服务不再接收任何请求,客户端会抛出Broken Pipe。检查系统状态执行top,发现CPU和内存
- 模式虽然精妙,却难完美,比如观察者模式中观察者生命周期的问题;比如访问者模式中循环依赖的问题等等;其它很多模式也存在这样那样的一些不足之处,
- 要将一个对象序列化,可是如果对象的属性为null的时候,我们想将属性为null的都去掉。在这里我使用Newtonsoft.Json.dll记
- 本文实例为大家分享了Android匹配关键字标红的具体代码,供大家参考,具体内容如下1. 单关键字匹配若只需匹配 搜索内容 可以
- Android 滑动返回Activity的实现代码近来玩微信的时候偶然发现,向左滑动朋友圈竟然可以返回主页,故引起兴趣特研究代码很简洁pac
- C#一些延时函数sleep延时方法System.Threading.Thread.Sleep(1000); //毫秒实现的是非独占性延时函数
- JDK * 的过程JDK * 采用字节重组,重新生成对象来替代原始对象,以达到 * 的目的。JDK中有一个规范,在ClassPath下
- Spring是一个非常流行的Java Web开发框架,它提供了强大的依赖注入、面向切面编程、声明式事务管理等功能,为开发者提供了高效、快速地
- 本文实例为大家分享了C#实现飞行棋的具体代码,供大家参考,具体内容如下游戏规则如果玩家A踩到了玩家B,玩家B退6格踩到了1幸运轮盘,a交换位
- 之前做过cookie实现记住密码,这次换成session记住密码又做了一遍,有很多收获。本次博客分为两部分。一部分是cookie和sessi
- private void txtBarCode_KeyPress(object sender, KeyPressEventArg
- 以前一直看见 i18N ,现在才知道原来 i18N 就是 Internationalization,因为以 i 开头,以 N 结尾,共18个
- 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成
- 本文实例为大家分享了java GUI学生图书管理的具体代码,供大家参考,具体内容如下- mysql数据库建表:1.book表 2.bs借书记
- 只使用try和finally不使用catch的原因和场景JDK并发工具包中,很多异常处理都使用了如下的结构,如AbstractExecuto