C#中string.Empty和null的區(qū)別詳解
這是一個及其常見的問題,網(wǎng)上已經(jīng)有關于這個問題的很多討論。但是我覺得都是不求甚解,有一些還是在誤導別人。下面我來說下我對這三者的理解,如有錯誤的地方請大家及時指正。
一:""與string.Empty我認為是一樣的。網(wǎng)上有一篇被轉(zhuǎn)載了幾十遍的文章是這樣說的string.Empty 不分配存儲空間,"" 分配一個長度為空的存儲空間,我認為這句話是錯誤并且含糊不清的。
1、實際上Empty是string類中的一個靜態(tài)的只讀字段,他的定義是這樣的:
public static readonly String Empty = "";
也就是說string.Empty的內(nèi)部實現(xiàn)是等于””的。
2、我要反駁string.Empty 不分配存儲空間,"" 分配一個長度為空的存儲空間這個觀點。首先string.Empty與""都會分配存儲空間,具體的說是都會在內(nèi)存的棧和堆上分配存儲空間。
有一點先說明一下,引用類型是將對象是實際數(shù)據(jù)保存在堆上, 將對象在堆上的地址保存在棧上。因此string.Empty與””都會在棧上保存一個地址這個地址占4字節(jié),指向內(nèi)存堆中的某個長度為0的空間,這個空 間保存的是string.Empty的實際值。這個我可以用VS2010跟蹤下內(nèi)存給大家演示。

上圖中的0x01e81228即是變量str在棧中存儲的地址。
對于"",請看下圖

這個圖的效果跟上圖是一樣的,也就是說””也是在棧上保存了一個地址。
3、CLR會對字符串進行優(yōu)化,所以””和string.Empty也都會被優(yōu)化。
聲明如下兩個變量
string str1=””;
string str2=””;
str1與str2的引用會是相同的也就是str1與str2在棧上保存的地址上相同的。請看下圖

上圖是str1的地址。

上圖是str2的地址
4、如果非要說””與string.Empty有什么不同的話,我覺得1是寫法不一樣,string.Empty看起來好看~!~。2是在優(yōu)化 方面稍有差別。string.Empty于c#對””在語法級別的優(yōu)化。這點可以通過string.Empty的內(nèi)部實現(xiàn)看出來。
public static readonly String Empty = "";
也就是說””是通過CLR進行優(yōu)化的,CLR會維護一個字符串池,以防在堆中創(chuàng)建重復的字符串。而string.Empty是一種c#語法級別 的優(yōu)化,是在C#編譯器將代碼編譯為IL(即MSIL)時進行了優(yōu)化,即所有對string類的靜態(tài)字段Empty的訪問都會被指向同一引用,以節(jié)省內(nèi)存 空間。
所以對””的優(yōu)化更依賴CLR。
給大家看一下二者編譯后的IL代碼:
string str1=””; 編譯后如下:
ldstr "" //從字符串池中取出一個””(實際上取的是地址)
stfld string ClassLibrary1.Class1::str1 //將””賦給str1(實際上賦的是地址)
string str2=string.Empty; 編譯后如下:
ldsfld string [mscorlib]System.String::Empty//取得string類的靜態(tài)字段Empty(實際上取的是地址)
stfld string ClassLibrary1.Class1::str2//將Empty賦給str2(實際上賦的是地址)
總結(jié):說了這么一大推我自己都覺得羅嗦,而且初學者朋友可能會看不懂。本人語文學的不好,表達能力一般還請大家諒解,下面我會挑要害來說。
“”與string.Empty在用法與性能上基本沒區(qū)別。string.Empty是在語法級別對””的優(yōu)化。
二、string.Empty與null的區(qū)別
因為string.Empty與””基本是一樣的,所以string.Empty與null的區(qū)別也就代表了””與null的區(qū)別。
1、 那就是string.Empty會在堆上占用一個長度為0的空間,而null不會。具體內(nèi)容如下:
string str1=””;
string str2=null;
如剛才所說str1會在棧上保存一個地址,這個地址占4字節(jié),指向內(nèi)存堆中的某個長度為0的空間,這個空間保存的是str1的實際值。
str2同樣會在棧上保存一個地址,這個地址也占4字節(jié),但是這個地址是沒有明確指向的,它哪也不指,其內(nèi)容為0x00000000。如下圖

相關文章
C#實現(xiàn)將像素轉(zhuǎn)換為頁面單位的方法
這篇文章主要介紹了C#實現(xiàn)將像素轉(zhuǎn)換為頁面單位的方法,涉及C#像素轉(zhuǎn)換在圖形繪制中的技巧,需要的朋友可以參考下2015-06-06
C#中IEnumerator<T>和IEnumerable的區(qū)別
在C#中,IEnumerator<T>和IEnumerable是用于實現(xiàn)迭代的接口,本文主要介紹了C#中IEnumerator<T>和IEnumerable的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2024-01-01
macOS系統(tǒng)下Vscode的python配置教程
這篇文章主要介紹了macOS系統(tǒng)下Vscode的python配置教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04

