const和readonly內部區別

來源:互聯網
上載者:User

const和readonly關鍵字也是面試中經常考到的問題,通常都是用來表示一個不可變的變數成員,那麼具體區別是什嗎?從用法上說,const只能以inline代碼的形式定義,而readonly既可以以inline代碼形式定義也可以通過構造方法定義。CLR中定義,readonly的變數只能在構造方法中賦值,而C#中inline代碼實際上是構造方法調用的一部分,因此readonly的變數可以以inline的方式賦值。

以上是文法方面的應用,那在實際上的用法上,還是有些微妙的變化,通常不易發覺,請看下面的代碼

在程式集ConstLib.dll中有一個類MyClass,定義了一個公開的靜態變數MaxCount

View Code

1     public static class MyClass
2     {
3         public const int MaxCount = 20;
4     }

然後另外一個應用程式ConstTest.exe 引用constLib.dll,並在代碼中作如下調用

View Code

1         static void Main(string[] args)
2         {
3             Console.WriteLine(MyClass.MaxCount);

5             Console.ReadLine();
6         }

毫無疑問,非常簡單的代碼,直接輸出20。

接下來更新MyClass的MaxCount的值為30,然後重新編譯ConstLib.dll,並更新到應用程式的所在目錄中,注意不能編譯應用程式。那麼這時候的輸出結果按預期那麼想應該是30才對,但實際上還是20,為什麼呢?

這就是const的特別之處,有多特別還是直接看產生的IL,查看ConstTestIL代碼(假設這時候MaxCount的值為20)

IL_0000:  nop
IL_0001:  ldc.i4.s   20
IL_0003:  call       void [mscorlib]System.Console::WriteLine(int32)

紅色代碼很明顯的表明了,直接載入20,沒有通過任何類型的載入然後得到對應變數的,也就是說在運行時沒有去載入ConstLib.dll,那麼是否意味著沒有ConstLib.dll也可以運行呢?答案是肯定的,刪除ConstLib.dll也可以運行,是否很詭異呢?也就解釋了之前的實驗,為什麼更新const變數的值之後沒有調用新的值,因為ConstText.exe在啟動並執行時候根本不會去載入ConstLib.dll。那麼20這個值是從哪來的呢?實際上CLR對於const變數做了特殊處理,是將const的值直接嵌入在產生的IL代碼中,在執行的時候不會再去請求dll載入。這也帶來了一個不容易發覺的bug,因此在引用其他程式集的const變數時,需考慮到版本更新問題,要解決這個問題就是把調用的應用程式再編譯一次就ok了。但實際程式部署更新時可能只更新個別檔案,這時候就必須用readonly關鍵字來解決這個問題。

 

接下來看readonly的版本

readonly

1     public static class MyClass
2     {
3         public static readonly int MaxCount = 20;
4     }

調用方代碼不變,接著看看ConstTest.exe產生的IL代碼

  IL_0001:  ldsfld     int32 [ConstLib]ConstLib.MyClass::MaxCount
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(int32)

很明顯載入代碼變了,一個很常見的ldsfld動作,請求了ConstLib.MyClass的MaxCount變數,是通過強制要求載入ConstLib來實現的。因此這時候更新MaxCount的值重新編譯之後,ConstText.exe還是不編譯,然後再執行就會看到新的值。而這時候如果刪除ConstLib.dll那麼,會出現運行時報錯找不到dll之類的異常。這也充分說明了對於readonly定義的變數是在運行時載入的。

 

總結const和readonly的最大區別(除文法外)

const的變數時嵌入在IL代碼中,編譯時間就載入好,不依賴外部dll(這也是為什麼不能在構造方法中賦值)。const在程式集更新時容易產生版本不一致的不管。

readonly的變數是在運行時載入,需請求載入dll,每次都擷取最新的值。

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.