const和readonly你真的懂嗎?

第二遍文章我打算把const和readonly的區別拿出來說下,由於寫代碼這麼久我都還沒搞清楚這二者的區別,實在有點慚愧,因此這一次我打算搞清楚它。數據庫

定義

來看看MSDN的解釋:函數

readonly:readonly關鍵字是能夠在字段上使用的修飾符。當字段聲明包括readonly修飾符時,該聲明引入的字段賦值只能做爲聲明的一部分,或者出如今同一類的構造函數中。性能

const使用 const 關鍵字來聲明某個常量字段或常量局部變量。 常量字段和常量局部變量不是變量而且不能修改spa

太多理論的講解有些人可能看了更犯暈,因此直接寫些代碼我以爲可能比較直觀好理解。code

 

舉例

咱們先來看下const對象

public class ConstTest
{
        class SampleClass
        {
            public int x;
            public int y;
            public const int c1 = 5;
            public const int c2 = c1 + 5;
            public static const int z=8;    //這個寫法錯誤,由於const是靜態常量,可看下面提供c1的IL語言圖片。
 
 
            //變量能夠在這裏初始化值,可是若是把const放在這裏初始化,編譯會出錯(賦值號左邊必須爲變量、屬性或索引器)
            public SampleClass(int p1, int p2)
            {
                x = p1;
                y = p2;
            }
        }
        static void Main()
        {
            SampleClass mC = new SampleClass(11, 22);
            Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y);
            Console.WriteLine("c1 = {0}, c2 = {1}",SampleClass.c1, SampleClass.c2);  //類型引用
        }
 }
/* Output
    x = 11, y = 22
    c1 = 5, c2 = 10
 */
來看下IL語言:
QQ截圖20151102230247
QQ截圖20151102230308

c2和y省略在這裏省略,從上面的圖咱們得出了一個結論:blog

那就是靜態常量,那什麼是靜態常量呢?靜態常量是指編譯器在編譯時候會對常量進行解析,並將常量的值替換成初始化的那個值。即圖中裏面的c1和c2,它們都是在編譯的時候值就肯定下來(c1=5,c2=10),這個相信你們也比較好理解。索引

咱們再來看readonly:圖片

public class ReadOnlyTest
{
        class SampleClass
        {
            public readonly int x;
            public  readonly int y = 25;
            public  static readonly int z=12;
       
            //無參構造函數初始化readonly常量
            public SampleClass()
            {
                y = 24;
            }
            //靜態無參構造函數內初始化static readonly常量      
            static SampleClass()
            {
                z = 23;
            }
            //有參構造函數初始化readonly常量
            public SampleClass(int p1, int p2)
            {
                x = p1;
                y = p2;
            }
        }

        static void Main()
        {
            //訪問靜態成員
            Console.WriteLine(SampleClass.z);

            //訪問非靜態成員
            SampleClass p1 = new SampleClass(11, 21);   // OK
            Console.WriteLine("p1: x={0}, y={1}", p1.x, p1.y);
            SampleClass p2 = new SampleClass();
            Console.WriteLine("p2: x={0}, y={1}", p2.x, p2.y);

            Console.ReadKey();
        }
}
 /*
 Output:
 23
 p1: x=11, y=21
 p2: x=0, y=24
    */
一樣的,來看IL語言:
QQ截圖20151102230308

咱們先看下什麼是動態常量:get

動態常量,是指值在運行的那一刻纔得到的,編譯器編譯期間將其標示爲只讀常量,而不用常量的值代替,這樣動態常量沒必要在聲明的時候就初始化,而能夠延遲到構造函數中初始化。

經過const和readonly的代碼咱們能夠得出如下結論:

1.readonly和static readonly定義的常量,指定初始值後(包括在構造函數內指定初始值)將不可更改,可讀不可寫。

2.static readonly常量,若是在構造函數內指定初始值,則必須是靜態無參構造函數,例如z參數的初始化過程。

3.const和static readonly定義的常量是靜態的,只能由類型直接訪問;而readonly定義的常量是非靜態的,只能由實例對象訪問。

const和readonly比較

1.const默認是靜態的,只能由類型訪問,不能和static同時使用,不然編譯錯誤;readonly默認是非靜態,由實例對象來訪問,能夠顯式使用static定義爲靜態成員。

2.const只能引用在值類型和string類型上,其餘引用類型常量必須聲明爲null,不然以new爲const引用類型常量賦值,編譯器會提示錯誤,緣由是構造函數初始化在運行時,而非編譯時;readonly只讀字段能夠是任意類型,可是對於引用類型字段來講,readonly不能限制對該對象實例成員的讀寫控制。

3.const必須在字段聲明時初始化;而readonly能夠在聲明時,或者構造函數中進行初始化,不一樣的構造函數能夠爲readonly常量實現不一樣的初始值

4.const能夠定義字段和局部變量;而readonly則只能定義字段

5.const因爲是靜態常量因此在編譯時會對常量進行解析,而readonly是動態常量在編譯期間編譯器將其標示爲只讀常量,而不用常量的值代替,這樣就沒必要在聲明的時候就初始化,而能夠延遲到構造函數中初始化

6.從應用角度來看,對於恆定不變且單獨使用的量來講,應該考慮聲明爲const常量,例如性能比,百分比等;而對於可能隨實際運行發生變化的量,應該考慮聲明readonly常量,例如日期或時間,數據庫中的主鍵id等

 

以上內容但願對一些朋友帶來幫助~~~

相關文章
相關標籤/搜索