C# 靜態(tài)常量(const)和動(dòng)態(tài)常量(static和readonly)用法和區(qū)別

C#中有兩種常量類型,分別為readonly(運(yùn)行時(shí)常量)與const(編譯時(shí)常量),本文將就這兩種類型的不同特性進(jìn)行比較并說明各自的適用場景。

工作原理

       readonly為運(yùn)行時(shí)常量,程序運(yùn)行時(shí)進(jìn)行賦值,賦值完成后便無法更改,因此也有人稱其為只讀變量。
       const為編譯時(shí)常量,程序編譯時(shí)將對(duì)常量值進(jìn)行解析,并將所有常量引用替換為相應(yīng)值。

下面聲明兩個(gè)常量:

public static readonly int A = 2; //A為運(yùn)行時(shí)常量
public const int B = 3; //B為編譯時(shí)常量
下面的表達(dá)式:
int C = A + B;
經(jīng)過編譯后與下面的形式等價(jià):
int C = A + 3;
可以看到,其中的const常量B被替換成字面量3,而readonly常量A則保持引用方式。
聲明及初始化
readonly常量只能聲明為類字段,支持實(shí)例類型或靜態(tài)類型,可以在聲明的同時(shí)初始化或者在構(gòu)造函數(shù)中進(jìn)行初始化,初始化完成后便無法更改。
const常量除了可以聲明為類字段之外,還可以聲明為方法中的局部常量,默認(rèn)為靜態(tài)類型(無需用static修飾,否則將導(dǎo)致編譯錯(cuò)誤),但必須在聲明的同時(shí)完成初始化。

數(shù)據(jù)類型支持

由于const常量在編譯時(shí)將被替換為字面量,使得其取值類型受到了一定限制。const常量只能被賦予數(shù)字(整數(shù)、浮點(diǎn)數(shù))、字符串以及枚舉類型。下面的代碼無法通過編譯:
public const DateTime D = DateTime.MinValue;
改成readonly就可以正常編譯:
public readonly DateTime D = DateTime.MinValue;

可維護(hù)性

readonly以引用方式進(jìn)行工作,某個(gè)常量更新后,所有引用該常量的地方均能得到更新后的值。
const的情況要稍稍復(fù)雜些,特別是跨程序集調(diào)用:

public class ClassA
{
    public static readonly int A = 2; //A為運(yùn)行時(shí)常量
    public const int B = 3; //B為編譯時(shí)常量
}

public class ClassB
{
    public static int C = ClassA.A + ClassA.B; //變量C的值為A、B之和 
}

Console.WriteLine(ClassB.C); //輸出"5"

假設(shè)Class1與Class2位于兩個(gè)不同的程序集,現(xiàn)在更改Class1中的常量值:

public class ClassA
 {
        public static readonly int A = 4; //A為運(yùn)行時(shí)常量
        public const int B = 5; //B為編譯時(shí)常量
 }

編譯ClassA并部署(注意:這時(shí)并沒有重新編譯ClassB),再次查看變量C的值:
Console.WriteLine(ClassB.C); //輸出"7"
結(jié)果可能有點(diǎn)出乎意料,讓我們來仔細(xì)觀察變量C的賦值表達(dá)式:
public static int C = ClassA.A + ClassA.B;
編譯后與下面的形式等價(jià):
public static int C = ClassA.A + 3;

因此不管常量B的值如何變,對(duì)最終結(jié)果都不會(huì)產(chǎn)生影響。雖說重新編譯ClassB即可解決這個(gè)問題,但至少讓我們看到了const可能帶來的維護(hù)問題。

性能比較
const直接以字面量形式參與運(yùn)算,性能要略高于readonly,但對(duì)于一般應(yīng)用而言,這種性能上的差別可以說是微乎其微。

適用場景
在下面兩種情況下:
a.取值永久不變(比如圓周率、一天包含的小時(shí)數(shù)、地球的半徑等)
b.對(duì)程序性能要求非??量?br> 可以使用const常量,除此之外的其他情況都應(yīng)該優(yōu)先采用readonly常量。

C#中的static 和Java中的static

簡單,兩者用法完全是一致的。從兩方面討論:

  1. 變量是屬于類的,不是實(shí)例級(jí)別的。只能通過類名調(diào)用,不能通過實(shí)例調(diào)用。
  2. 如果在定義時(shí)就賦值了,那么在類初始化的時(shí)候,最先完成所有靜態(tài)變量的賦值。但是要注意,所有靜態(tài)變量的初始化順序是無法確定的。

C# 中的const 和Java中的finnal

很長一段時(shí)間我一直認(rèn)為兩者是相同的作用,無非是變量初始化后不能更改,即只能在定義時(shí)或者構(gòu)造函數(shù)中賦值。然而這僅僅只是片面的,下面將為大家詳細(xì)分析:

1.修飾變量

準(zhǔn)確的說C#中的const 等價(jià)于 Java中的static final,也就是說,Java中final不具有static的功能。而C#中的const具有static的功能。因此在C#中 public static const string 等將于 public const string。

2.修飾類和方法

此時(shí)Java中的final類似C#中的sealed,就是說,final修飾的類不能被繼承,final修飾的方法不能被覆蓋。

而C#中的const不能修飾類和方法。

問題:

1. 私有靜態(tài)成員的作用(private static 變量)

字面表示私有的,類外不能使用;靜態(tài)的,全局變量??瓷先ズ苊埽植荒鼙活愅馐褂?,要全局的有什么用。問得好,類中全局也是很有意義的,例如 private static int a = 5,那么就可以保證變量a在類的初始化過程中將被優(yōu)先初始化(在構(gòu)造函數(shù)執(zhí)行之前)。這樣如果對(duì)象A的初始化需要對(duì)象B的實(shí)例,那么就可以用這種申明,以保證在類A在構(gòu)造函數(shù)中能夠使用類B的實(shí)例。同時(shí)private又能夠保證類B的實(shí)例只能在類A中使用,起到很好的密封作用。

2. 私有最終成員作用(private final 變量)

在類構(gòu)造函數(shù)完成前必須對(duì)該成員完成初始化,一旦定義不許更改;該成員只能在本類中使用。實(shí)例,子類中都不能使用。

private static final修飾的成員在申明的時(shí)就被賦值,保證在構(gòu)造函數(shù)中可以被使用,一個(gè)被private static final修飾的成員通常表示其他組件的一個(gè)實(shí)例,且變量是類中的全局變量。

private final 修飾的成員在構(gòu)造中被賦值,表示它是該類全局的私有成員變量,且該類的構(gòu)造需要傳入他們的初始值,才能完成類的初始化。

C# conststatic readonly區(qū)別
const:用const修飾符聲明的成員叫常量,是在編譯期初始化并嵌入到客戶端程序
static readonly: 用static readonly修飾符聲明的成員依然是變量,只不過具有和常量類似的使用方法:通過類進(jìn)行訪問、初始化后不可以修改。但與常量不同的是這種變量是在運(yùn)行期初始化。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 幾種語言的特性 匯編程序:將匯編語言源程序翻譯成目標(biāo)程序編譯程序:將高級(jí)語言源程序翻譯成目標(biāo)程序解釋程序:將高級(jí)語...
    囊螢映雪的螢閱讀 3,056評(píng)論 1 5
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,621評(píng)論 1 32
  • 來說下c/c++中的const的用法。在英語中常數(shù)的一種表達(dá)是“中的const的”,在編程中可能是借用了這個(gè)單詞(...
    Jack_Cui閱讀 3,912評(píng)論 0 3
  • 注:這是第三遍讀《C語言深度解剖》,想想好像自從大學(xué)開始就沒讀完過幾本書,其中譚浩強(qiáng)的那本《C語言程序設(shè)計(jì)(第四版...
    HavenXie閱讀 1,909評(píng)論 1 6
  • 目錄 什么是靜態(tài)常量(Const)和動(dòng)態(tài)常量(Readonly) 靜態(tài)常量(Const)和動(dòng)態(tài)常量(Readonl...
    慕城祉宇流年殤閱讀 357評(píng)論 0 0

友情鏈接更多精彩內(nèi)容