时间:2021-05-20
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 :true3.总结
最后对string下点结论:
1.string在clr中不是用newobj指令创建,而是用ldstr指令创建!而且string拥有值类型的特征,但是在内存上是引用类型,存在托管堆上面;
2.string是sealed修饰的,所以不能被子类集成;
3.当创建内容相同的时候,string是指向同一地址的,而且每次操作string都会生成新的地址(string的恒定性);
4.对于大量拼接的话还是使用StringBuilder,它是动态的不像string是恒定的,但就是创建StringBuilder代价比较大,所以小拼接用string在性能上可能还更好!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
学过C#的人都知道string类型,但是string作为一种特殊的引用类型还有一个重要的特征就是恒定性,或者叫不可变性,即Immutable。作为不可变类型,最
C#中的string是比特殊的类,说引用类型,但不存在堆里面,而且Stringstr=newString("HelloWorld")这样的重装也说没有的。我们先
不知道大家有没有发现,在c#string类型可以写成string和String,那么,它们有什么区别呢?string是c#中的类;String是Framewor
string类型是C#的基元类型之一,它是一个引用类型,对应FCL中的System.String类型。string类型和普通的引用类型相比有什么样的相同点和不同
本文实例为大家分享了C#强制转换和尝试转换的方法,供大家参考,具体内容如下将String[]类型的Object类型,转换为String[]类型:publicst