C#中的static、readonly與const的比較

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常量。

相關文章
相關標籤/搜索