string、Empty和null三者的區別

本文轉自  http://www.bitscn.com/pdb/dotnet/201003/181883.htmlhtml

string、Empty和null三者的區別

時間:2010-03-01 00:00  來源:網管之家bitsCN.com 字體:[ ]

  這是一個及其常見的問題,網上已經有關於這個問題的不少討論。可是我以爲都是不求甚解,有一些仍是在誤導別人。下面我來講下我對這三者的理解,若有錯誤的地方請你們及時指正。swift

  一:""與string.Empty我認爲是同樣的。網上有一篇被轉載了幾十遍的文章是這樣說的string.Empty 不分配存儲空間,"" 分配一個長度爲空的存儲空間,我認爲這句話是錯誤而且含糊不清的。c#

  一、實際上Empty是string類中的一個靜態的只讀字段,他的定義是這樣的:性能

  public static readonly String Empty = "";字體

  也就是說string.Empty的內部實現是等於」」的。優化

  二、我要反駁string.Empty 不分配存儲空間,"" 分配一個長度爲空的存儲空間這個觀點。首先string.Empty與""都會分配存儲空間,具體的說是都會在內存的棧和堆上分配存儲空間。spa

  有一點先說明一下,引用類型是將對象是實際數據保存在堆上, 將對象在堆上的地址保存在棧上。所以string.Empty與」」都會在棧上保存一個地址這個地址佔4字節,指向內存堆中的某個長度爲0的空間,這個空 間保存的是string.Empty的實際值。這個我能夠用VS2010跟蹤下內存給你們演示。htm

  上圖中的0x01e81228便是變量str在棧中存儲的地址。對象

  對於"",請看下圖內存

  這個圖的效果跟上圖是同樣的,也就是說」」也是在棧上保存了一個地址。

  三、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的地址。

  四、若是非要說」」與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是在語法級別對」」的優化。

  2、string.Empty與null的區別

  由於string.Empty與」」基本是同樣的,因此string.Empty與null的區別也就表明了」」與null的區別。

  一、  那就是string.Empty會在堆上佔用一個長度爲0的空間,而null不會。具體內容以下:

  string str1=」」;

  string str2=null;

  如剛纔所說str1會在棧上保存一個地址,這個地址佔4字節,指向內存堆中的某個長度爲0的空間,這個空間保存的是str1的實際值。

  str2一樣會在棧上保存一個地址,這個地址也佔4字節,可是這個地址是沒有明確指向的,它哪也不指,其內容爲0x00000000。以下圖

相關文章
相關標籤/搜索