const 與 readonly知多少

來源:互聯網
上載者:User

      儘管你寫了很多年的C#的代碼,但是可能當別人問到你const與readonly的區別時候,還是會小小的愣一會吧~

      筆者也是在看歐立奇版的《.Net 程式員面試寶典》的時候,才發現自己長久以來竟然在弄不清出兩者的情況下,混用了這麼長的時間。的確,const與readonly 很像,都是將變數聲明為唯讀,且在變數初始化後就不可改寫。那麼,const與readonly 這兩個修飾符到底區別在什麼地方呢?其實,這個牽扯出C#語言中兩種不同的常量類型:靜態常量(compile-time constants)和動態常量(runtime constants)。這兩者具有不同的特性,錯誤的使用不僅會損失效率,而且還會造成錯誤。

      首先先解釋下什麼是靜態常量以及什麼是動態常量。靜態常量是指編譯器在編譯時間候會對常量進行解析,並將常量的值替換成初始化的那個值。而動態常量的值則是在啟動並執行那一刻才獲得的,編譯器編譯期間將其標示為唯讀常量,而不用常量的值代替,這樣動態常量不必在聲明的時候就初始化,而可以延遲到建構函式中初始化。

      當你大致瞭解上面的兩個概念的時候,那麼就可以來說明const與readonly了。const修飾的常量是上述中的第一種,即靜態常量;而readonly則是第二種,即動態常量。那麼區別可以通過靜態常量與動態常量的特性來說明:

      1)const修飾的常量在聲明的時候必須初始化;readonly修飾的常量則可以延遲到建構函式初始化 

      2)const修飾的常量在編譯期間就被解析,即常量值被替換成初始化的值;readonly修飾的常量則延遲到啟動並執行時候

      此外const常量既可以聲明在類中也可以在函數體內,但是static readonly常量只能聲明在類中。

      

      可能通過上述純概念性的講解,對有些初學者有些暈乎。下面就一些例子來說明下:      

using System;
class P
{
    static readonly int A=B*10;
    static readonly int B=10;   
    public static void Main(string[] args)
    {
        Console.WriteLine("A is {0},B is {1} ",A,B);
    }
}

 

      對於上述代碼,輸出結果是多少?很多人會認為是A is 100,B is 10吧!其實,正確的輸出結果是A is 0,B is 10。好吧,如果改成下面的話:

using System;
class P
{
    const int A=B*10;
    const int B=10;   
    public static void Main(string[] args)
    {
        Console.WriteLine("A is {0},B is {1} ",A,B);
    }
}

 

       對於上述代碼,輸出結果又是多少呢?難道是A is 0,B is 10?其實又錯了,這次正確的輸出結果是A is 100,B is 10。

       那麼為什麼是這樣的呢?其實在上面說了,const是靜態常量,所以在編譯的時候就將A與B的值確定下來了(即B變數時10,而A=B*10=10*10=100),那麼Main函數中的輸出當然是A is 100,B is 10啦。而static readonly則是動態常量,變數的值在編譯期間不予以解析,所以開始都是預設值,像A與B都是int類型,故都是0。而在程式執行到A=B*10;所以A=0*10=0,程式接著執行到B=10這句時候,才會真正的B的初值10賦給B。如果,你還是不大清楚的話,我們可以藉助於微軟提供的ILDASM工具,只需在Vs 2008 Command下輸入ILDASM就可以開啟,如下所示:

        

        

        分別開啟上述兩個代碼編譯後產生的可執行檔,如所示:

                       

                   static readonly可執行程式的結構                                                                const可執行程式的結構

 

        在上述兩張圖中都可以看到A與B常量,分別雙擊節點可以看出其中的差異:

              

                   static readonly修飾的常量A                                                                      const修飾的常量A

    

           

                  static readonly修飾的常量B                                                                       const修飾的常量B

 

         從中可以看出,const修飾的常量在編譯期間便已將A,B的字面值算出來了,而static readonly修飾的常量則未解析,所以在Main函數中有以下的區別:

                    

                              static readonly程式的Main函數                                                            const程式的Main函數

 

      從Main函數中我們可以看出,const的那個程式的輸出直接是100與10,而readonly在輸出的時候確實P::A與P::B,即將A與B常量的值延遲到啟動並執行時候才去確定,故輸出是0與10。

      那麼對於靜態常量以及動態常量還有什麼特性呢?其實,靜態常量只能被聲明為簡單的資料類型(int以及浮點型)、枚舉、布爾或者字串型,而動態常量則除了這些類型,還可以修飾一些物件類型。如DateTime類型,如下:

      //錯誤

      const DateTime time=new DateTime(); 

      //正確

      static readonly DateTime time=new DateTime();

 

     上述錯誤在於不能使用new關鍵字初始化一個靜態常量,即便是一個實值型別,因為new將會導致到運行時才能確定值,與靜態變數編譯時間就確定字面值有悖。     

      歐書上最後給出了對靜態常量與動態常量之間的比較,如下表所示:      

      

      

       最近隨筆較少,希望這篇能給一些朋友帶來一些協助~ 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.