C#兩種常量型別,readonly(執行時常量)與const(編譯時常量)
阿新 • • 發佈:2018-12-13
C#中有兩種常量型別,分別為readonly(執行時常量)與const(編譯時常量),本文將就這兩種型別的不同特性進行比較並說明各自的適用場景。 工作原理 readonly為執行時常量,程式執行時進行賦值,賦值完成後便無法更改,因此也有人稱其為只讀變數。 const為編譯時常量,程式編譯時將對常量值進行解析,並將所有常量引用替換為相應值。 下面宣告兩個常量: public static readonly int A = 2; //A為執行時常量 public const int B = 3; //B為編譯時常量 下面的表示式: int C = A + B; 經過編譯後與下面的形式等價: int C = A + 3; 可以看到,其中的const常量B被替換成字面量3,而readonly常量A則保持引用方式。 宣告及初始化 readonly常量只能宣告為類欄位,支援例項型別或靜態型別,可以在宣告的同時初始化或者在建構函式中進行初始化,初始化完成後便無法更改。 const常量除了可以宣告為類欄位之外,還可以宣告為方法中的區域性常量,預設為靜態型別(無需用static修飾,否則將導致編譯錯誤),但必須在宣告的同時完成初始化。 資料型別支援 由於const常量在編譯時將被替換為字面量,使得其取值型別受到了一定限制。const常量只能被賦予數字(整數、浮點數)、字串以及列舉型別。下面的程式碼無法通過編譯: public const DateTime D = DateTime.MinValue; 改成readonly就可以正常編譯: public readonly DateTime D = DateTime.MinValue; 可維護性 readonly以引用方式進行工作,某個常量更新後,所有引用該常量的地方均能得到更新後的值。 const的情況要稍稍複雜些,特別是跨程式集呼叫: public class Class1 { public static readonly int A = 2; //A為執行時常量 public const int B = 3; //B為編譯時常量 } public class Class2 { public static int C = Class1.A + Class1.B; //變數C的值為A、B之和 } Console.WriteLine(Class2.C); //輸出"5" 假設Class1與Class2位於兩個不同的程式集,現在更改Class1中的常量值: public class Class1 { public static readonly int A = 4; //A為執行時常量 public const int B = 5; //B為編譯時常量 } 編譯Class1並部署(注意:這時並沒有重新編譯Class2),再次檢視變數C的值: Console.WriteLine(Class2.C); //輸出"7" 結果可能有點出乎意料,讓我們來仔細觀察變數C的賦值表示式: public static int C = Class1.A + Class1.B; 編譯後與下面的形式等價: public static int C = Class1.A + 3; 因此不管常量B的值如何變,對最終結果都不會產生影響。雖說重新編譯Class2即可解決這個問題,但至少讓我們看到了const可能帶來的維護問題。 效能比較 const直接以字面量形式參與運算,效能要略高於readonly,但對於一般應用而言,這種效能上的差別可以說是微乎其微。 適用場景 在下面兩種情況下: a.取值永久不變(比如圓周率、一天包含的小時數、地球的半徑等) b.對程式效能要求非常苛刻 可以使用const常量,除此之外的其他情況都應該優先採用readonly常量。