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常量只能被賦予數字(整數、浮點數)、字符串以及枚舉類型。下面的代碼沒法經過編譯:it
public const DateTime D = DateTime.MinValue;
改爲readonly就能夠正常編譯:編譯
public readonly DateTime D = DateTime.MinValue;
可維護性
readonly以引用方式進行工做,某個常量更新後,全部引用該常量的地方均能獲得更新後的值。
const的狀況要稍稍複雜些,特別是跨程序集調用:class
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常量。