zoukankan      html  css  js  c++  java
  • C# 中 string.Empty、""、null的差别

    一、string.Empty 和 ""                                                           原文1   原文2

    1、Empty是string类中的一个静态的只读字段,它是这样定义的:

    // Represents the empty string. This field is read-only. 
    public static readonly string Empty; 

    也就是说 string.Empty 的内部实现是等于 "" 的。二者在优化方面稍有差别,string.Empty 是 C# 对 "" 在语法级别的优化。这点可以从上面 string.Empty 的内部实现看出来。也就是说 "" 是通过 CLR(Common Language Runtime)进行优化的,CLR 会维护一个字符串池,以防在堆中创建重复的字符串。而 string.Empty 是一种 C# 语法级别的优化,是在C#编译器将代码编译为 IL (即 MSIL )时进行了优化,即所有对string类的静态字段Empty的访问都会被指向同一引用,以节省内存空间。

            PS:MSIL(Microsoft Intermediate Language (MSIL)微软中间语言)。

    2、引用类型的数据将对象在堆上的地址保存在"" 都会分配存储空间,具体的说是都会在内存的栈和堆上分配存储空间。因此string.Empty与“”都会在栈上保存一个地址,这个地址占4字节,指向内存堆中的某个长度为0的空间,这个空间保存的是string.Empty的实际值。

    测试代码如下:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
       
    namespace string_Empty 
    { 
        class Program 
        { 
            static void Main(string[] args) 
            { 
                stringTest(); 
            } 
       
            public static void stringTest() 
            { 
                string str; 
                string str1; 
                string str2; 
                string str3; 
       
                str = string.Empty; 
                str1 = string.Empty; 
                str2 = ""; 
                str3 = ""; 
            } 
        } 
    } 

    Go to disassembly:

    可以发现这种写法下,string.Empty 和 "" 的地址是相同的。  

            由于 string.Empty 定义为 static readonly ,又根据上面运行结果得知, string.Empty 不会申请新的内存,而是每次去指向固定的静态只读内存区域,""也一样。    

            string.Empty 与 "" 在用法与性能上基本没区别。string.Empty 是在语法级别对 "" 的优化。

    二、string.Empty 和 "" 与 null 的区别

            代码如下:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
       
    namespace string_Empty 
    { 
        class Program 
        { 
            static void Main(string[] args) 
            { 
                stringTest(); 
            } 
       
            public static void stringTest() 
            { 
                string str; 
                string str1; 
                string str2; 
       
                str = string.Empty; 
                str1 = ""; 
                str2 = null; 
            } 
        } 
    } 

    Go to disassembly:

     从运行结果可以看出,string.Empty 和 "" 在栈和堆上都分配了空间,而 null 只在栈上分配了空间,在堆上没有分配,也即变量不引用内存中的任何对象。

    道虽迩,不行不至;事虽小,不为不成。
  • 相关阅读:
    Firemonkey绑定对象列表
    Firemonkey 自定义Button的Style
    Delphi中使用GDI+进行绘图(2)
    Delphi中使用GDI+进行绘图(1)
    很好用的一个类:TJvAppXMLFileStorage
    我的Win32开发抉择,Delphi老将复出
    实现动态的XML文件读写操作
    一个简单的统计图像主颜色的算法(C#源代码)
    开始使用THREE.JS
    C++应用程序在Windows下的编译、链接(一)概述
  • 原文地址:https://www.cnblogs.com/LeeMacrofeng/p/14415040.html
Copyright © 2011-2022 走看看