转载: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 三者的区别的更多相关文章

  1. string、Empty和null三者的区别

    string.Empty和null三者的区别 本文转自  http://www.bitscn.com/pdb/dotnet/201003/181883.html 时间:2010-03-01 00:00 ...

  2. asp.net(c#)中String.Empty、NULL、"" 三者到底有啥区别和联系?

    开门见山,首先看下面代码,你认为结果分别是什么? string str = string.Empty; string str1 = ""; string str2 = null; ...

  3. C#中String.Empty、NULL与""三者的区别

    String.Empty和""是一样的,都是空,习惯用string.empty. Null和他们就有区别了,就是没有值,也没分配地址,此处可以理解成什么都没有.

  4. string.empty和null的区别

    关于String.Empty和Null的问题是这样的,这两个都是表示空字符串,其中有一个重点是string str1= String.Empty和 string str2=null 的区别,这样定义后 ...

  5. C# null,string.Empty,"",DBNull 的区别

    [null] null 在C# 中是一个关键字,表示不引用任何对象的空引用的文字值. null 是引用类型变量的默认值. 普通值类型不能为 null. null 在 VS 中定位不出来具体是怎么定义的 ...

  6. String.Empty、null、“” 区别

    概念准备: 1.引用类型是将对象是实际数据保存在堆中, 将对象在堆中的地址保存在栈中. 2.值类型直接将实际数据存放在堆中,不会将对象在堆中的地址保存在栈中. 一.String.Empty和" ...

  7. string.Empty与null与""

    (1)NULLnull 关键字是表示不引用任何对象的空引用的文字值.null 是引用类型变量的默认值.那么也只有引用型的变量可以为NULL,如果int i=null,的话,是不可以的,因为Int是值类 ...

  8. String声明为NULL和""的区别

    代码虐我千百遍,我待代码如初恋. String 声明为 NULL 则声明了一个变量不指向任何一块地址,则 length()会出现错误. 声明为"",则是一个长度为0的字符串.

  9. String.Empty,NULL和""的区别

    String.Empty,NULL和""的区别 string.Empty就相当于"" 一般用于字符串的初始化 比如: string a; Console.Wri ...

随机推荐

  1. [HNOI2003]消防局的设立 树形dp // 贪心

    https://www.luogu.org/problemnew/show/P2279 一开始就想到了贪心的方法,不过一直觉得不能证明. 贪心的考虑是在深度从深到浅遍历每个结点的过程中,对于每个没有覆 ...

  2. jmeter每10个停一会实现方案

    foreach控制器中加个if控制器,if控制器条件${__groovy("${__counter(TRUE,)}".toInteger() % 10 == 0,)},再往if控制 ...

  3. svn 基础

    安装,略过. 快速创建.配置及启动项目 创建项目 svnadmin create /home/svn/project_name #创建名为project_name的项目(/home/svn为自定义创建 ...

  4. script nGrinder_TestRunnerInsertMysqlSingle.groovy

    s 阿里巴巴Java开发规范手册.zip http://dl.iteye.com/topics/download/ffc4ddcf-8b65-3b3c-b146-96468e2baf40 /** 关于 ...

  5. java io系列09之 FileDescriptor总结

    本章对FileDescriptor进行介绍 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_09.html FileDescriptor 介绍 Fil ...

  6. java io系列19之 CharArrayWriter(字符数组输出流)

    本章,我们学习CharArrayWriter.学习时,我们先对CharArrayWriter有个大致了解,然后深入了解一下它的源码,最后通过示例来掌握它的用法. 转载请注明出处:http://www. ...

  7. CentOS7 上以 RPM 包方式安装 Oracle 18c 单实例

    安装阿里云 YUM 源 https://opsx.alibaba.com/mirror?lang=zh-CN 一.安装Oracle数据库 1.安装 Oracle 预安装 RPM yum -y loca ...

  8. C++回顾day02---<引用>---待补充

    一:引用概念---引用就是为一个变量起一个别名 每个变量都是指向一块内存空间的标识,引用就是重新设置一个标识,但是这个标识还是指向同一个内存空间 和指针类似(其实引用本质就是使用了一个常指针 cons ...

  9. [JUC-2]AbstractQueuedSynchronizer源码分析

    AbstactQueuedSynchronizer的基本数据结构 AbstractQueuedSynchronizer的基本数据结构为Node,关于Node,JDK作者写了详细的注释,这里我大致总结几 ...

  10. 那些年我们没能bypass的xss filter[from wooyun]

    原文链接:http://zone.wooyun.org/content/6899 小弟初学xss才10天.不过个人很喜欢收集xss payload.在这里把自己平时挖xss时会用到的payloads列 ...