C# String类的特性

来源:互联网 发布:艺考软件 编辑:程序博客网 时间:2024/05/21 15:00

两个特性:不可变性,驻留池。

参考链接:https://msdn.microsoft.com/zh-cn/library/s1wwdcbf#Immutability

首先要清楚Systrm.String是一个又值语议的引用类型,也就是说,String不同于大多数的引用类型。其比较操做是对字符串值进行比较,而不是比较字符串的位置。字符串是一个Char类型的序列,创建字符串后,不能在当前内存位置上改变,如不能缩短,不能在后面追加字符,也不能改变其中的字符。当然,字符串的值时可以修改的,但是修改后的字符串要存放在新的内存位置,原来的字符串仍保留,直到被垃圾收集器删除。Systrm.Text.StringBuilder类提供了一组在缓存中构造和管理字符串的方法。当操作完成后,期内容转换为一个字符串。如果是应用大量使用了字符串连接和修改的操作,应该使用StringBuilder。


方法/步骤
1创建字符串:先要声明一个string类型的变量,并给它赋值。值可以是直接量字符串,也可以通过连接操作动态创建。这个过程往往忽视,大多数人如果想要改善代码效率,并不会考虑这个方面。
2字符串拘留:
那么先要区分值和引用类型在内存中是如何分配存储的。值类型存储在托管栈上,而引用类型存储在托管堆上。当然,很多人不知道CLR还在内存中预留了第三个区域。这个区就是拘留池,用来存储编译期间所有的字符串直接量,简单说这个池就是避免存储重复的字符串值。下图,分清托管栈和托管堆之后,“张学友”和“刘德华”都是在拘留池(量池)。如图2:拘留池实现为一个散列表,散列表键key是实际的字符串,它指针引用托管堆上的相关字符串对象。str4的一个实例"abc"放在托管堆里,当str1,str2,str3的量也是“abc”时,CLR发现已经有同样的字符串已经存在在内存中,将"adc"放入拘留池里,而不是创建一个新的字符串。只是让str1,str2,str3指向str4的对象。
为了检验拘留池的实际效果。用“==”操作符比较字符串,另外使用Object.RefernceEqueals方法来比较字符串的地址。
Console.WriteLine(str4==str1);//true;(值是相同的)
Console.WriteLine(str4==str2);//true;
Console.WriteLine(RefernceEqueals(str4,str1));//false(地址不同)
str1,str2,str3内存地址和str4不同。
C#的关于String类深入解析
C#的关于String类深入解析
3由于每次创建字符串都要检查拘留池,因此会影响性能,所有拘留池中是不存放动态创建的值。不过,为此提供一个String.Intern方法,以便有选择地向拘留池增加动态创建的字符串。如图2:新建

C#的关于String类深入解析
C#的关于String类深入解析

string c ="c";

string str5 ="ab"+c;//值为abc;
Console.WriteLine(RefernceEquals(str5,str1));//false.虽然值一样,但是地址不一样。str5系统重新分配有内存。
str5=string.Intern(str5);
Console.WriteLine(RefernceEquals(str5,str1));//true.
string.Intern方法在拘留池中搜索str5的值(abc);由于它已经在拘留池中,所以不用再增加。该方法返回已有对象Object的引用,并赋给str5,由于str5和str1指向相同的对象“abc”,所以最后一条语句为true。而str5所创建的对象会在下一次的垃圾收集时被释放并清除。
String.Intern方法使得字符串变量可以利用引用比较,只有字符串变量出现在多个比较中时才会用到。

0 0