转载: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. threading:线程创建、启动、睡眠、退出

    1.方法一:将要执行的函数作为参数传递给threading.Thread() import threading import time def func(n): global count time.s ...

  2. phpmyadmin拿webshell

    思路:就是利用mysql的一个日志文件.这个日志文件每执行一个sql语句就会将其执行的保存.我们将这个日志文件重命名为我们的shell.php然后执行一条sql带一句话木马的命令.然后执行菜刀连接之! ...

  3. 冒泡排序Java版

    package dataStructureAlgorithmReview.day01; import java.util.Arrays; /** * 冒泡 * @author shundong * * ...

  4. 关于交叉熵(cross entropy),你了解哪些

    二分~多分~Softmax~理预 一.简介 在二分类问题中,你可以根据神经网络节点的输出,通过一个激活函数如Sigmoid,将其转换为属于某一类的概率,为了给出具体的分类结果,你可以取0.5作为阈值, ...

  5. Spring Boot笔记一 输出hello

    开始学习Spring Boot了,本篇文章你可以学到 1.Spring Boot的基本配置,输出一句hello 许嵩 2.Spring boot打包成jar包 一.Spring boot的基本配置 这 ...

  6. jmeter元件执行顺序及简介

    最近在学习Jmeter,在进行实操之前,先查看了官方文档.因为官方文档是英文的,为了方便以后查看,自己翻译了一部分,中间个别地方根据自己的理解简单地翻译了部分.如果翻译等有问题,欢迎指正. 一.执行顺 ...

  7. STM32学习笔记:【004】USART串口通信

    版本:STM32F429 Hal库v1.10 串口通信能够实现两块电路之间不同的通信,在开发中作为打印调试也是一门利器(printf重定向). 补充一点小知识: 1. weak修饰符修饰的函数,说明这 ...

  8. 2016vijos 1-2 股神小L(堆)

    维护前i天的最优解,那么在后面可能会对前面几天的买卖情况进行调整 如果前面买入,买入的这个在后面一定不会卖出 如果前面卖出,卖出的这个可能会在后面变成买入,因为买这个,卖后面的会获得更多的收益 用一个 ...

  9. navicat and connection is being used

    1.在已经保存的连接上上编辑,测试连接成功,但是点击连接就会一直提示 connection is being used 2.需要新建一个连接,才能使用,不能再已保存的上面修改

  10. ajax方式下载文件

    在web项目中需要下载文件,由于传递的参数比较多(通过参数在服务器端动态下载指定文件),所以希望使用post方式传递参数.通常,在web前端需要下载文件,都是通过指定<a>标签的href属 ...