string.Empty, "" 和 null 三者的区别
转载:http://www.cnblogs.com/mxxblog/archive/2013/08/22/3275387.html
这是一个及其常见的问题,网上已经有关于这个问题的很多讨论。但是我觉得都是不求甚解,有一些还是在误导别人。下面我来说下我对这三者的理解,如有错误的地方请大家及时指正。
一:""与string.Empty我认为是一样的。网上有一篇被转载了几十遍的文章是这样说的string.Empty 不分配存储空间,"" 分配一个长度为空的存储空间,我认为这句话是错误并且含糊不清的。
1、实际上Empty是string类中的一个静态的只读字段,他的定义是这样的:
public static readonly String Empty = "";
也就是说string.Empty的内部实现是等于””的。
2、我要反驳string.Empty 不分配存储空间,"" 分配一个长度为空的存储空间这个观点。首先string.Empty与""都会分配存储空间,具体的说是都会在内存的栈和堆上分配存储空间。
有一点先说明一下,引用类型是将对象是实际数据保存在堆上, 将对象在堆上的地址保存在栈上。因此string.Empty与””都会在栈上保存一个地址这个地址占4字节,指向内存堆中的某个长度为0的空间,这个空 间保存的是string.Empty的实际值。这个我可以用VS2010跟踪下内存给大家演示。
上图中的0x01e81228即是变量str在栈中存储的地址。
对于"",请看下图
这个图的效果跟上图是一样的,也就是说””也是在栈上保存了一个地址。
3、CLR会对字符串进行优化,所以””和string.Empty也都会被优化。
声明如下两个变量
string str1=””;
string str2=””;
str1与str2的引用会是相同的也就是str1与str2在栈上保存的地址上相同的。请看下图
上图是str1的地址。 上图是str2的地址。
可见str1于str2的地址是相同的,也就是说str1会在堆上占用一个长度为0的空间,而str2不会在堆上开辟新的空间, str2于str1在堆上共享同一空间。
同理对于
string str3=string.Empty;
string str4= string.Empty;
str3与str4的地址也是相同的。也是在内存堆上共享同一空间。如下图
上图是str3的地址。 上图是str4的地址。
4、如果非要说””与string.Empty有什么不同的话,我觉得1是写法不一样,string.Empty看起来好看~!~。2是在优化 方面稍有差别。string.Empty于c#对””在语法级别的优化。这点可以通过string.Empty的内部实现看出来。
public static readonly String Empty = "";
也就是说””是通过CLR进行优化的,CLR会维护一个字符串池,以防在堆中创建重复的字符串。而string.Empty是一种c#语法级别 的优化,是在C#编译器将代码编译为IL(即MSIL)时进行了优化,即所有对string类的静态字段Empty的访问都会被指向同一引用,以节省内存 空间。
所以对””的优化更依赖CLR。
给大家看一下二者编译后的IL代码:
string str1=””; 编译后如下:
ldstr "" //从字符串池中取出一个””(实际上取的是地址)
stfld string ClassLibrary1.Class1::str1 //将””赋给str1(实际上赋的是地址)
string str2=string.Empty; 编译后如下:
ldsfld string [mscorlib]System.String::Empty//取得string类的静态字段Empty(实际上取的是地址)
stfld string ClassLibrary1.Class1::str2//将Empty赋给str2(实际上赋的是地址)
总结:说了这么一大推我自己都觉得罗嗦,而且初学者朋友可能会看不懂。本人语文学的不好,表达能力一般还请大家谅解,下面我会挑要害来说。
“”与string.Empty在用法与性能上基本没区别。string.Empty是在语法级别对””的优化。
二、string.Empty与null的区别
因为string.Empty与””基本是一样的,所以string.Empty与null的区别也就代表了””与null的区别。
1、 那就是string.Empty会在堆上占用一个长度为0的空间,而null不会。具体内容如下:
string str1=””;
string str2=null;
如刚才所说str1会在栈上保存一个地址,这个地址占4字节,指向内存堆中的某个长度为0的空间,这个空间保存的是str1的实际值。
str2同样会在栈上保存一个地址,这个地址也占4字节,但是这个地址是没有明确指向的,它哪也不指,其内容为0x00000000。如下图
string.Empty, "" 和 null 三者的区别的更多相关文章
- string、Empty和null三者的区别
string.Empty和null三者的区别 本文转自 http://www.bitscn.com/pdb/dotnet/201003/181883.html 时间:2010-03-01 00:00 ...
- asp.net(c#)中String.Empty、NULL、"" 三者到底有啥区别和联系?
开门见山,首先看下面代码,你认为结果分别是什么? string str = string.Empty; string str1 = ""; string str2 = null; ...
- C#中String.Empty、NULL与""三者的区别
String.Empty和""是一样的,都是空,习惯用string.empty. Null和他们就有区别了,就是没有值,也没分配地址,此处可以理解成什么都没有.
- string.empty和null的区别
关于String.Empty和Null的问题是这样的,这两个都是表示空字符串,其中有一个重点是string str1= String.Empty和 string str2=null 的区别,这样定义后 ...
- C# null,string.Empty,"",DBNull 的区别
[null] null 在C# 中是一个关键字,表示不引用任何对象的空引用的文字值. null 是引用类型变量的默认值. 普通值类型不能为 null. null 在 VS 中定位不出来具体是怎么定义的 ...
- String.Empty、null、“” 区别
概念准备: 1.引用类型是将对象是实际数据保存在堆中, 将对象在堆中的地址保存在栈中. 2.值类型直接将实际数据存放在堆中,不会将对象在堆中的地址保存在栈中. 一.String.Empty和" ...
- string.Empty与null与""
(1)NULLnull 关键字是表示不引用任何对象的空引用的文字值.null 是引用类型变量的默认值.那么也只有引用型的变量可以为NULL,如果int i=null,的话,是不可以的,因为Int是值类 ...
- String声明为NULL和""的区别
代码虐我千百遍,我待代码如初恋. String 声明为 NULL 则声明了一个变量不指向任何一块地址,则 length()会出现错误. 声明为"",则是一个长度为0的字符串.
- String.Empty,NULL和""的区别
String.Empty,NULL和""的区别 string.Empty就相当于"" 一般用于字符串的初始化 比如: string a; Console.Wri ...
随机推荐
- Python网络编程之socket编程
什么是Socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面 ...
- jmeter5.0 while controller使用总结
while controller 配合sql使用的方式 在while控制器条件中填空,这样当里面的请求断言失败后就会跳出循环 在while控制器条件中填LAST,当里面的请求断言失败后就会跳出循环,如 ...
- beeswarm-蜜蜂图
一.beeswarm作为一维散点图包R包,可以生成点不重复的图,与stripchart的区别就是等值点不会重叠到一起,下图展示了stripchart与beeswarm图的区别: stripchart( ...
- Kafka权威指南 读书笔记之(一)初识Kafka
发布与订阅消息系统 数据(消息)的发送者(发布者)不会直接把消息发送给接收者,这是发布与订阅消息系统的一个特点.发布者以某种方式对消息进行分类,接收者(订阅者)订阅它们, 以便接收特定类型的消息.发布 ...
- Hbase记录-shell脚本嵌入hbase shell命令
第一种方式:hbase shell test.txt test.txt:list 第二种方式:<<EOF重定向输入 我们经常在shell脚本程序中用<<EOF重定向输入,将我们 ...
- C#设计模式(11)——装饰者模式
1.装饰者模式介绍 装饰者顾名思义就是对一个类添加一些额外的装饰(功能).我们想给一个对象添加一些额外的功能又不改变对象内方法的签名怎么做呢?最常用的方法就是继承了,子类继承父类,然后重写父类的方法. ...
- 能使 Oracle 索引失效的六大限制条件【转】
. 引用自: http://www.cnblogs.com/orientsun/archive/2012/07/05/2577351.html 总结得非常到位 Oracle 索引的目标是避免全表扫描 ...
- ACM-ICPC 2018 焦作赛区网络预赛 A Magic Mirror(签到)
https://nanti.jisuanke.com/t/31710 题意 若输入的是Jessie或jessie,输出Good guy!,否则输出Dare you say that again? 分析 ...
- Timus 1132 Square Root(二次剩余 解法2)
不理解,背板子 #include<cstdio> using namespace std; int Pow(int a,int b,int p) { ; ) ) res=1LL*a*res ...
- java 的三种代理
java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作, ...