c 的const和readonly使用小結

2022-01-12 00:14:11 字數 2545 閱讀 1580

前言:從上週開始看<>第三版,剛剛看完了第四和第七兩章,這兩章都算常識,但是有很多基礎知識和術語理解不是很深入,所以看得有點慢,計畫每兩周寫點心得,是以成文。

1、應用場景重現

乙個簡單的應用程式解決方案,如下:

其中,類庫csharplib裡定義乙個簡單的類sometype如下:

namespace csharplib

}

using system;

.", sometype.constfield);

console.writeline("readonly field is .", sometype.readonlyfield);

console.readkey();}}

}

這樣這個控制台應用程式的輸出就都是50,這個結果應該是每個開發人員都預期的,沒有任何可疑之處。

當我們把類庫csharplib中的常量都改變時:

namespace csharplib

}

2、注意點總結

為什麼會發生上面的現象呢?從c#的常量的本質說起。

(1)、什麼是常量(書中原話摘錄)

「常量(constant)是乙個特殊的符號,它是乙個從不變化的值。定義常量符號時,它的值必須能在編譯時確定。確定之後,編譯器將常量的值儲存到程式集的元資料中。常量總是被視為靜態成員,而不是例項成員。**引用乙個常量符號時,編譯器會在定義常量的程式集的元資料中查詢該符號,提取常量的值,並將值嵌入生成的il**中。由於常量的值直接嵌入**,所以在執行時,不需要為常量分配記憶體。除此之外,不能獲取常量的位址,也不能以傳引用的方式傳遞常量。這些限制同時意味著,常量沒有很好的跨程式集版本控制特性。「

(2)、靜態常量和動態常量

簡單來說,用const修飾的就是靜態常量(compile-time constants),而且它是隱式靜態的。動態常量(runtime constants)的值是在執行時獲得的,il中將其標為唯讀常量,而不是用常量的值代替。

下面對二者的特點進行簡單比較:

靜態常量

動態常量

記憶體分配無有

可使用型別

較少的c#基元型別,如string,int32等等

任意型別

初始化賦值

宣告變數時同時賦值

可在建構函式中賦值

何時發揮作用

編譯時進行替換,可生成元資料

相當於類中的資料成員

通過上述分析,我們可以理解1中所產生的輸出不一致現象,是因為const欄位constfield已經嵌入到控制台應用程式的il**中(獲取constfield欄位並不從類庫的dll檔案中載入),從il中我們可以看得很清楚:

.method private hidebysig static void  main(string args) cil managed

." il_0006: ldc.i4.s 50 //const欄位沒有變化

il_0008: box [mscorlib]system.int32

il_000d: call void [mscorlib]system.console::writeline(string,

object)

il_0012: nop

il_0013: ldstr "readonly field is ."

il_0018: ldsfld int32 [csharplib]csharplib.sometype::readonlyfield

il_001d: box [mscorlib]system.int32

il_0022: call void [mscorlib]system.console::writeline(string,

object)

il_0027: nop

il_0028: call valuetype [mscorlib]system.consolekeyinfo [mscorlib]system.console::readkey()

il_002d: pop

il_002e: ret

} // end of method program::main

而不是像static readonly欄位一樣從記憶體載入類庫程式集。如果應用程式需獲取新值,也必須重新編譯,或者使用readonly欄位。

3、模擬問題

我記得以前看過的一篇博文,是討論列舉使用中輸出不一致情況的,google了一下。您可以參考這一篇小心列舉陷阱進行比較,如果您對il有了解,可以簡單從il著手分析對比,更能加深理解。

總結:const和readonly在程式設計實踐中經常用到,理解它們的基本原理,對於開發和維護都是非常有必要的。在類庫開發定義常量的時候,個人偏向於使用static readonly組合關鍵字。

C 的頂層const和底層const

指標如果新增const修飾符時有兩種情況 1指向常量的指標 代表不能改變其指向內容的指標。宣告時const可以放在型別名前後都可,拿int型別來說,宣告時 const int和int const 是等價的。宣告指向常量的指標也就是底層const,下面舉乙個例子 int num a 1 int con...

C 頂層const和底層const

當我們定義指標和變數的時候,有時候希望定義成const型,就是不希望程式中改變自己定義的變數,一旦有 試圖改變定義好的const型的變數,在編譯的時候就會直接報錯。指標本身也是乙個變數物件,指標所指的變數也是乙個變數物件。當定義const int p i的時候是指標不可變還是變數i不可變呢?這就涉及...

C 頂層const和底層const

頂層const表示物件本身是乙個常量 底層const表示不能通過指標或引用改變所指向的物件 例如const int a 42 頂層const,不能改變a的值,int只能有頂層const 指標 int b 12 const int b1 b 底層const,不能通過b1改變a的值,可以理解為b1指向c...