Net复习笔记:第八部分:特殊的String
特殊的String
- string不是用newobj指令创建,而是用ldstr指令创建
- 在类型表现上面string为值类型语义,在内存上面string为引用类型,存储在托管堆上面
- 两次创建内容相同的string对象可以指向相同的内存地址
- String是密封的不能被子类继承
- String是夸程序域的可以在不同的程序域里面访问
- 字符串恒定行,是指字符串已经创建就不能更改,
字符串驻留机制
string strA = "abcdef";
string strB = "abcdef";
Response.Write(ReferenceEquals(strA, strB)); //返¤¦Ì回?为atrue;
string strC = "abc";
string strD = strC + "def";
Response.Write(ReferenceEquals(strA, strD)); //返¤¦Ì回?为afalse
strD=string.Intern(strD);
Response.Write(ReferenceEquals(strA, strD)); //返¤¦Ì回?为atrue
对于字符串net为了高效性能,提供了专门的处理方案,那就是字符串驻留(基于字符串的很定性),net在ClR内部维护了一个哈希表,其中表的key就是字符串的内容,值就是字符串在托管堆里面的地址,当在创建一个新的字符串的时候,net就会先这个新的哈希表里查找是否已经存在要创建的字符串,如果是存在的,那就吧找到的已经存在的字符串的值赋给新创建的字符串,让他们保持指向同一个托管堆地址,如果不存在加重新分配地址,这就是为什么
string strA = "abcdef";
string strB = "abcdef";
Response.Write(ReferenceEquals(strA, strB)); //返¤¦Ì回?为atrue;
返回的会是一个true
而对于
string strC = "abc";
string strD = strC + "def";
Response.Write(ReferenceEquals(strA, strD)); //返¤¦Ì回?为afalse
返回的是false是因为,strD的字符串是动态生成的,这样的字符串不会被添加到哈希表中,所以他们没有指向相同的地址,判等结果就是false
对于动态生成的字符串没有添加到哈希表里,当我们需要高效的比较两个字符串是否相等的时候,可以手动的启动字符串驻留机制,那就是string的两个静态的方法(string.Intern(strD); string.IsInterned(strD))
strD=string.Intern(strD);
Response.Write(ReferenceEquals(strA, strD)); //返¤¦Ì回?为atrue
因为使用了strD=string.Intern(strD);启用了字符串驻留,所以strA和strD指向了同一个内存地址,所以返回的结果就是true
但是需要注意的是 strH=“abc”+“def”;这样的是会启动字符串驻留机制的,因为字符串的恒定性,所有字符串可以跨域访问,
String和system.string的关系:string是C#的基元类型,和int char一样,不同的语言对基元类型识别可能不同,
System.string是框架类库,string和system.string有直接的映射关系从IL来看二者没有什么不同
String和StringBuilder比较
- 在链接字符串方面StringBuilder要比string效率上高出很多,所以StringBuilder适合于大数据字符串的链接,
- string是恒定的而StringBuilder是动态的,
- StringBuilder对象创建代价较大,在字符串链接较小的时候慎用,
- StringBuilder会导致性能的浪费,只要大量的不定次数的字符串才考虑StringBuilder小数据的字符串链接看不出StringBuilder的优势,而且会消耗整体性能