前言:從上週開始看<>第三版,剛剛看完了第四和第七兩章,這兩章都算常識,但是有很多基礎知識和術語理解不是很深入,所以看得有點慢,計畫每兩周寫點心得,是以成文。1、應用場景重現
乙個簡單的應用程式解決方案,如下:
其中,類庫csharplib裡定義乙個簡單的類sometype如下:
namespace csharplib}
using system;這樣這個控制台應用程式的輸出就都是50,這個結果應該是每個開發人員都預期的,沒有任何可疑之處。.", sometype.constfield);
console.writeline("readonly field is .", sometype.readonlyfield);
console.readkey();}}
}
當我們把類庫csharplib中的常量都改變時:
namespace csharplib2、注意點總結}
為什麼會發生上面的現象呢?從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而不是像static readonly欄位一樣從記憶體載入類庫程式集。如果應用程式需獲取新值,也必須重新編譯,或者使用readonly欄位。." 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
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...