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

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

工作原理

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

下面聲明兩個常量:

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

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

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

可維護(hù)性

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

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

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

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

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

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

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

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

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

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

C#中的static 和Java中的static

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

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

C# 中的const 和Java中的finnal

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

1.修飾變量

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

2.修飾類和方法

此時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í)行之前)忧侧。這樣如果對象A的初始化需要對象B的實(shí)例石窑,那么就可以用這種申明,以保證在類A在構(gòu)造函數(shù)中能夠使用類B的實(shí)例蚓炬。同時private又能夠保證類B的實(shí)例只能在類A中使用松逊,起到很好的密封作用。

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

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

private static final修飾的成員在申明的時就被賦值耐亏,保證在構(gòu)造函數(shù)中可以被使用,一個被private static final修飾的成員通常表示其他組件的一個實(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)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市琼讽,隨后出現(xiàn)的幾起案子必峰,更是在濱河造成了極大的恐慌,老刑警劉巖钻蹬,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吼蚁,死亡現(xiàn)場離奇詭異,居然都是意外死亡问欠,警方通過查閱死者的電腦和手機(jī)肝匆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顺献,“玉大人旗国,你說我怎么就攤上這事∽⒄” “怎么了能曾?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肿轨。 經(jīng)常有香客問我寿冕,道長,這世上最難降的妖魔是什么椒袍? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任驼唱,我火速辦了婚禮,結(jié)果婚禮上驹暑,老公的妹妹穿的比我還像新娘玫恳。我一直安慰自己辨赐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布京办。 她就那樣靜靜地躺著掀序,像睡著了一般。 火紅的嫁衣襯著肌膚如雪臂港。 梳的紋絲不亂的頭發(fā)上森枪,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音审孽,去河邊找鬼县袱。 笑死,一個胖子當(dāng)著我的面吹牛佑力,可吹牛的內(nèi)容都是我干的式散。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼打颤,長吁一口氣:“原來是場噩夢啊……” “哼暴拄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起编饺,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤乖篷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后透且,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撕蔼,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年秽誊,在試婚紗的時候發(fā)現(xiàn)自己被綠了鲸沮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡锅论,死狀恐怖讼溺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情最易,我是刑警寧澤怒坯,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站耘纱,受9級特大地震影響敬肚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜束析,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望憎亚。 院中可真熱鬧员寇,春花似錦弄慰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扳缕,卻和暖如春慌闭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背躯舔。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工驴剔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粥庄。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓丧失,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惜互。 傳聞我的和親對象是個殘疾皇子布讹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容