string、Empty和null三者的区别

本文转自  http://www.bitscn.com/pdb/dotnet/201003/181883.html

时间:2010-03-01 00:00  来源:网管之家bitsCN.com 字体:[  ]
 

  这是一个及其常见的问题,网上已经有关于这个问题的很多讨论。但是我觉得都是不求甚解,有一些还是在误导别人。下面我来说下我对这三者的理解,如有错误的地方请大家及时指正。

  一:""与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 三者的区别

    转载:http://www.cnblogs.com/mxxblog/archive/2013/08/22/3275387.html 这是一个及其常见的问题,网上已经有关于这个问题的很多讨论.但是我觉得 ...

  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. MyBatis原理分析之四:一次SQL查询的源码分析

    上回我们讲到Mybatis加载相关的配置文件进行初始化,这回我们讲一下一次SQL查询怎么进行的. 准备工作 Mybatis完成一次SQL查询需要使用的代码如下: ) { ); ) { throw ne ...

  2. ruby发送邮件方法

    #encoding:utf-8require 'mail'def send_email sum,fail,case_path,name,receive smtp = { :address => ...

  3. 打造H5里的“3D全景漫游”秘籍

    近来风生水起的VR虚拟现实技术,抽空想起年初完成的“星球计划”项目,总结篇文章与各位分享一下制作基于Html5的3D全景漫游秘籍. QQ物联与深圳市天文台合作,在手Q“发现新设备”-“公共设备”里,连 ...

  4. ASP.NET在IIS7.5(IIS7)配置伪静态

    http://jingyan.baidu.com/article/67508eb4ff92c69cca1ce49a.html 我相信不少站长都遇到个头疼的问题..NET如何在IIS7或者IIS7.5下 ...

  5. a new blog from MarsEdit

    终于在网上找到了一款mac 下的blog写作和发布工具了. 先测试一下.

  6. Spark BlockManager的通信及内存占用分析(源码阅读九)

    之前阅读也有总结过Block的RPC服务是通过NettyBlockRpcServer提供打开,即下载Block文件的功能.然后在启动jbo的时候由Driver上的BlockManagerMaster对 ...

  7. 用ADO.NET存入数据库

    点击按钮存入登录名和密码: const string connstr = @"data source=USER-20160705UW\JSQL;initial catalog=Test;in ...

  8. Laravel 使用多个数据库的问题。

    这几天在使用Laravel 开发一个系统.这个系统连2个数据库.一个名为blog,一个名为center. center 数据库的作用是作为用户中心.可能会有其他几个系统相连,属于公用数据库.主要是用来 ...

  9. Junit4参数化测试实现程序与用例数据分离

    http://touchfu.iteye.com/blog/732930 现状:你是不是还在为自己的TestCase代码杂乱无章而苦恼,咎其根本还在于针对不同的用例,输入参数和mock信息的组装全部作 ...

  10. 转 Dynamics CRM Alert and Notification JavaScript Methods

    http://www.powerobjects.com/2015/09/23/dynamics-crm-alert-and-notification-javascript-methods/ Befor ...