天天看點

[C#] readonly vs const

C#中的readonly和const兩個關鍵字都可以用來定義系統變量,那兩者之間有什麼差別呢?

1. const變量指派後,就不可以對其進行修改。且在定義時就需要給它指派,使用const修飾的變量是static的。可以使用YourClass.ConstantName的方式進行通路;

2. readonly變量可以在定義時指派,也可以在構造方法中指派或者修改定義時賦給的初始值;

另外還有一個細微的差别。看下面的場景,我在AssemblyA中定義了一個類如下:

public class Readonly_VS_Const
    {
        public const int I_Const_Value = 100;

        public readonly int I_Readonly_Value = 20;

        public Readonly_VS_Const()
        {
            I_Readonly_Value = 55;
        }
    }      

在AssemblyB中引用了AssemblyA,并且使用了這些常量,

static void Main(string[] args)
    {
        int constValue = Readonly_VS_Const.I_Const_Value;

        Readonly_VS_Const vs = new Readonly_VS_Const();

        int readonlyValue = vs.I_Readonly_Value;

        Console.WriteLine("Const Value:{0}--Readonly Value:{1}", 
            constValue, readonlyValue);

        Console.ReadKey();
    }      

檢視一下IL代碼,

[C#] readonly vs const

注意檢視使用黃色和綠色框标記的兩行代碼。

假設AssemblyA和AssemblyB編譯完成後均放在AssemblyB的目錄下

1. const變量類似與一種替換的方式,直接将定義的100寫入到IL代碼中。當我修改了I_Const_Value的值為200後,AssemblyB需要在程式重新編譯後才能獲得更新後的數值;

2. readonly的變量值,很像ref類型,readonly值不會直接寫入到AssemblyB的IL代碼中,這就意味者如果AssemblyA中readonly的值被修改後,你隻需要重新編譯一下AssemblyA即可。AssemblyB在調用時會找到根據變量的記憶體位置讀取修改後的值。

static readonly vs const,

onst和static readonly的确很像:通過類名而不是對象名進行通路,在程式中隻讀等等。在多數情況下可以混用。

二者本質的差別在于,const的值是在編譯期間确定的,是以隻能在聲明時通過常量表達式指定其值。而static readonly是在運作時計算出其值的,是以還可以通過靜态構造函數來指派。

請看下面的例子:

class Program
    {
        static readonly int A = B * 10;

        static readonly int B = 10;

        static void Main(string[] args)
        {
            Console.WriteLine("A: {0} B: {1}", A, B);
        }
    }      

結果如下:

[C#] readonly vs const

将static readonly修改為const,

class Program
    {
        const int A = B * 10;

        const int B = 10;

        static void Main(string[] args)
        {
            Console.WriteLine("A: {0} B: {1}", A, B);
        }
    }      

結果如下:

[C#] readonly vs const

那麼為什麼是這樣的呢?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。

感謝您的閱讀!