深入理解.net - 4.你必须知道的String
为什么要单独写string,主要是它太常用了,同时又太特殊了,特殊到CLR对它的处理都和其它对象不一样。简直可以称为VIP用户啊。本文并不是一篇介绍如何使用string的文章,而是旨在阐述string的一些本质特性。
引用类型
首先要明确string对象是引用类型的,具有引用类型一切特征,上篇文章也写了关于引用类型的的一些知识,有兴趣的可以看看。引用类型是创建在堆上的,默认是按值传递的。按这个理论来看string就有一些有意思的现象了。
public static void ChangeStringValue(string tmp)
{
tmp = "bbb";
}
public static void Main(string[] args)
{
string str = "aaa";
ChangeStringValue(str);
Console.WriteLine(str);
}
上面代码基本上会写程序的人都知道输入的结果是:aaa
但是string身为一个引用类型调用ChangeStringValue方法时传递的应该是Main方法中str变量的值(即对象实例的引用)啊,在此强调一点就是引用类型和值类型一样默认都是按值传递的。输出的结果为什么不是 bbb 呢?
答案就是:Immutable
恒定不变的(Immutable)String
MSDN上是这么介绍的:
A String object is called immutable (read-only), because its value cannot be modified after it has been created. Methods that appear to modify a String object actually return a new String object that contains the modification.
大体意思就是说:string对象是不变的或只读的,因为创建之后它的值是不能修改的。表面上修改一个string对象实际上返回的是一个包含了修改内容的新的string对象。
所以呢,每次修改string变量其实都是新建了一个string对象。
将上述代码的简单内存模型所示如下:

so,当我们调用ChangeStringValue方法时,传递的确实是string对象的引用,此时变量tmp和str存储的都是"aaa"字符串的引用,
但是由于string的Immutable特殊性,当我们执行tmp= "bbb"; 时,CLR会先创建了一个新的字符串"bbb",然后将ChangeStringValue方法的参数tmp的值修改成字符串"bbb"的引用了。但Main方法中的变量str的值并没有被改变还是指向字符串"aaa"的。所以输出的结果是:aaa
通常我们使用引用类型时,对引用类型的操作是会直接影响到外部的对象的,但由于Immutable特性,string对象的值是无法修改的,为什么要这么设计呢?这又牵扯出另一个有意思的特性。
字符串的驻留(String Interning)
什么是驻留呢,大牛们讨论了很多我就不卖弄了,引用下Artech大神 《再说String》文章中的一段描述如下:
String的驻留机制实际上是在SystemDomain中进行的。当CLR被加载之后,会在SystemDomain对应的managed heap中创建一个Hash table的数据结构,我们可以称这个Hashtable为Interning table,因为它是被用来保存被驻留的string的,Interning table的Key为string本身,Value为string对象的地址。
当我们的托管程序(无论对于那个AppDomain)需要一个string的时候,CLR首先在这个Hashtable根据这个string的hash code试着在Interning table中找对应的Item。如果成功找到,则直接把对应的引用返回,否则就在SystemDomain对应的managed heap中创建该string,并加入到Interning table中,并把引用返回。所以我们说字符串的驻留是基于整个进程的,是可以跨AppDomain共享的,就是这个道理。
显而易见,lock一个string对象是多么恐怖的事情;大量的字符串拼接也是非常浪费性能的,推荐使用StringBuilder。
总结
string是个引用类型,string Immutable,String Interning,这些都是你必须要知道的。臭不要脸的借用了下大神的书名,致敬下经典。
末尾参考链接吐血推荐一波,绝对看的爽歪歪,相信你会收获到更多。
参考链接
- 《你必须知道的.NET》
- String Class - MSDN
- 字符串的驻留(String Interning)- Artech
- 深入理解string和如何高效地使用string - Artech
- 再说String - Artech
- 关于String的终极解释
深入理解.net - 4.你必须知道的String的更多相关文章
- 【源码分析】你必须知道的string.IsNullOrEmpty && string.IsNullOrWhiteSpace
写在前面 之前自信撸码时踩了一次小坑,代码如下: private static void AppServer_NewMessageReceived(WebSocketSession session, ...
- 必须知道的String知识点
1.String 类型的概述 Java中String就是Unicode字符序列,例如,字符串"Java\u2122"由5个Unicode字符J.a.v.a和 ™ 组成.不像C/C+ ...
- Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor
Webservice WCF WebApi 注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...
- C#刨根究底:《你必须知道的.NET》读书笔记系列
一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...
- (转)【推荐】初级.NET程序员,你必须知道的EF知识和经验
转自:http://www.cnblogs.com/zhaopei/p/5721789.html [推荐]初级.NET程序员,你必须知道的EF知识和经验 阅读目录 [本文已下咒.先顶后看,会涨 ...
- Apple的App Analytics统计平台你必须知道的Q&A整理与翻译
Apple的App Analytics统计平台你必须知道的Q&A整理与翻译 Apple最近在iTunesConnect里最新发布了App Analytics统计平台,提供了现有友盟统计平台和自 ...
- [你必须知道的.NET] 第八回:品味类型---值类型与引用类型(上)-内存有理
原文地址:http://kb.cnblogs.com/page/42318/ 系列文章导航: [你必须知道的.NET] 开篇有益 [你必须知道的.NET] 第一回:恩怨情仇:is和as [你必须知道的 ...
- [你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望
发布日期:2009.05.22 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. /// <summary> /// 本文开始,将以& ...
- 《jQuery风暴》第2章 必须知道的JavaScript知识
第2章 必须知道的JavaScript知识 JavaScript是jQuery应用的基础,掌握JavaScript这门语言是使用jQuery的基础条件.本章不会全面细致的讲解JavaScript的全部 ...
随机推荐
- VS2010中NET4项目中使用LOG4NET办法
两年以前项目中是用的log4net.dll是net2.0环境下面的,最近在官网http://logging.apache.org/log4net/download_log4net.cgi找到了net4 ...
- 从头到尾解析Hash表算法
via:点击打开链接 十一.从头到尾解析Hash 表算法 作者:July.wuliming.pkuoliver 出处:http://blog.csdn.net/v_JULY_v. 说明:本文分 ...
- LDA主体模型
一)LDA作用 传统判断两个文档相似性的方法是通过查看两个文档共同出现的单词的多少,如TF-IDF等,这种方法没有考虑到文字背后的语义关联,可能在两个文档共同出现的单词很少甚至没有,但两个文档是相似的 ...
- 基于GraphCuts图割算法的图像分割----OpenCV代码与实现
转载请注明出处:http://blog.csdn.net/wangyaninglm/article/details/44151213, 来自:shiter编写程序的艺术 1.绪论 图切割算法是组合图论 ...
- 【Visual C++】游戏编程学习笔记之四:透明动画实现
本系列文章由@二货梦想家张程 所写,转载请注明出处. 本文章链接:http://blog.csdn.net/terence1212/article/details/44224963 作者:ZeeCod ...
- Bookmarkable Pages
Build a Bookmarkable Edit Page with JDeveloper 11g Purpose In this tutorial, you use Oracle JDevel ...
- C语言笔试经典--求分数数列的和
题目: 求数组的和 2 3/2 5/3 8/5 13/8 21/13 ... 求前20项的和 //求分数数列的和 #include<stdio.h> // ...
- 【Nginx】下载,请求限速,根据URL参数限速
这个场景是限制单个连接的下载速度,还有限制单个IP的连接数,或者单位时间内的请求数,实验环境 nginx1.9.x. 小例子为主,具体的细节请多看文档. 限制下载速度 location /downlo ...
- error C4996: 'strcpy': This function or variable may be unsafe.
vs2012用strcpy遇到的错误. 错误描述:error C4996: 'strcpy': This function or variable may be unsafe. Consider us ...
- JAVA加密技术-----MD5 与SHA 加密
关于JAVA的加密技术有很多很多,这里只介绍加密技术的两种 MD5与 SHA. MD5与SHA是单向加密算法,也就是说加密后不能解密. MD5 ---信息摘要算法,广泛用于加密与解密技术,常用于文件校 ...