深入理解.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的全部 ...
随机推荐
- hive发杂数据结构的使用,struct,array,map
一个简单介绍http://jimi68.iteye.com/blog/980573 一般的复杂介绍:http://songpo-ath-taobao-com.iteye.com/blog/140513 ...
- 《java入门第一季》之面向对象面试题(this和super的区别)
this和super的区别? 分别是什么呢? this代表本类对象的引用. super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员) 怎么用呢? A:调用成员变量 this.成员变量 ...
- Unity Editor 编写unity插件类
在unity写了一个编辑类,基于iTweenpath插件,为了更方便的操作iTweenpath,顺便练习UnityEditor的操作,写了一个CreateiTweenPath,放在Editor文件夹中 ...
- MongoDB 3.0新增特性一览
转自:http://blog.sina.com.cn/s/blog_48c95a190102vedr.html 引言 在历经版本号修改(2.8版本直接跳到3.0版本)和11个rc版本之后,MongoD ...
- SharePoint 2010 电子书下载网站推荐
最近一直搜集SharePoint2010的资料,偶尔发现一个网站还不错,推荐给大家,皮皮书屋http://www.ppurl.com/tag/sharepoint,里面有很多SharePoint201 ...
- obj-c编程15[Cocoa实例03]:MVC以及归档化示例
前面的博文里介绍了归档和解档,这里我们把它实际应用到一个简单的代码中去,将它作为一个多文档应用程序的打开和保存的背后支持.另外这里介绍一下MVC思想,这个在任何语言里都会有,它是一种设计思想,主要可以 ...
- 关于在vim中的查找和替换
1,查找 在normal模式下按下/即可进入查找模式,输入要查找的字符串并按下回车. Vim会跳转到第一个匹配.按下n查找下一个,按下N查找上一个. Vim查找支持正则表达式,例如/vim$匹配行尾的 ...
- 工作中EF遇到的问题
EF的条件中,无法用转格式,时间差作为条件,这时在EF6中,可以用 DbFunctions 这个类,例如: db.NewsComments.Any( (entity.PostDate - p.Pos ...
- android传值
需求 OneActivity向TwoActivity传值name=hzs,然后TwoActivity向OneActivity传值sex=Y 第一步:OneActivity向TwoActivity传值n ...
- 利用Python进行数据分析
最近在阅读<利用Python进行数据分析>,本篇博文作为读书笔记 ,记录一下阅读书签和实践心得. 准备工作 python环境配置好了,可以参见我之前的博文<基于Python的数据分析 ...