[C#.NET] 定義常數時用 readonly 好? 還是 const 好?

  • 56651
  • 0
  • 2013-07-05

[C#.NET] 定義常數時用 readonly 好? 還是 const 好?

在C#內我們可以使用兩種方式來宣告常數,const (C# 參考)readonly (C# 參考)

執行階段常數readonly
public static readonly int Start = 0;

編譯時期常數const
public const int End = 10;

兩種方式有相同的意義但背卻有不同的運作行為,使用不當的話可能會造成一些問題發生,我們在定義常數的時候會建議使用readonly而不是const,雖然說使用const的效能比使用static readonly效能好一些,但是整體的靈活性及方便性都是static readonly勝出的。

1.const 僅能用於數字和字串,而readonly可以是任意型態。

image

 

2.const能在方法中使用,readonly不行。(常數不應該是宣告在方法裡)

3.const 是在編譯時期產生的,readonly是在運行時產生的,假設我在有一個方法

在IL底下會看到以下:

image

用Reflector會看到以下:

image

引用一個readonly常數時是引用其變數,而引用const是引用其值,這將會影響執行時的相容性。

 


接下來我們來看看對於實際的專案它們兩個會有什麼不同??

首先我先建立一個類別庫專案並輸入ClassLibrary1


namespace ClassLibrary1
{
    public class Class1
    {
        public static readonly int Start = 0;
        public const int End = 10;
    }
}

 

 

然後再建立一個主控台應用程式,加入ClassLibrary1.dll

image

在main使用了Class1.Start及Class1.End


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = Class1.Start; i < Class1.End; i++)
            {
                Console.WriteLine("value is {0}", i);
            }
            Console.ReadKey();
        }
    }
}

 

執行結果如下:

image

 

在ConsoleApplication1.exe裡我們一直快樂的使用這兩個常數,ConsoleApplication1.exe也很正常的在客戶端執行著,有天PM跟我講說常數的定義有誤,必須要修改一下,很直覺的我只修改了ClassLibrary1裡的常數並編譯成dll,然後將ClassLibrary1.dll發佈到上去(將dll檔案copy到ConsoleApplication1.exe相對應資料夾),然後直接執行ConsoleApplication1.exe。

 


namespace ClassLibrary1
{
    public class Class1
    {
        public static readonly int Start = 9;
        public const int End = 20;
    }
}

 

image

 

怪了,直接跑 ConsoleApplication1.exe 的執行結果怎麼跟我想的不太一樣。

image

 

追根究底一下,原來Class.End編譯後變成10,難怪結果不是對的。

image

把ConsoleApplication1.exe專案打開來重新編譯就能得到我要的結果了,需要重新編譯的應用程式表示抽換的還不夠乾淨或是有其他問題,如果一個大的系統裡面全部的檔案都需要重新編譯,表示你需要更新的檔案不只一個。

image

 


後記:

本來將專案設計的相關靈活,用戶可以很容易抽換,直接拿新版的dll蓋過去就好,但是沒注意到背後的運作原理反倒會被將了一軍;聰明的你看完小的實作相信你應該知道要選什麼好了。

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo