C#筆記 – 常量
常量
-
常量值從不變化,因此總是被視為靜態成員
-
const int someConst = 1; -
//Check in ildasm someConst : private static literal int32 -
常量值必須能在編譯時確定,確定後,編譯器將常量保存到程序集元數據中
- 因此,常量類型必須是編譯器可以識別的基元類型
- C#允許定義非基元類型的常量,但值需設為null
-
定義常量將導致元數據的創建
- 代碼引用常量時,編譯器在定義常量的程序集的元數據中查找該常量並提取常量的值,然後將其嵌入生成的IL代碼中
- 因此,由於常量值直接嵌入代碼中,所以運行時不需要為常量分配任何內存
- 另外,不能獲取常量地址,也不能以傳引用的方式傳遞常量
-
常量在版本控制上非常不方便
-
假如有以下一個定義了常量的dll
-
public sealed class SomeLibraryType { public const int MaxEntriesInList = 1000; }
-
-
有引用了上述dll,並引用了常量的exe
-
public sealed class Program { public static void Main() { Console.WriteLine("Max Entries supported in list: " + SomeLibraryType.MaxEntriesInList); Console.ReadLine(); } }
-
-
在生成exe時,編譯器會注意到引用的常量,並將常量直接嵌入到應用的IL代碼中;而不是去加載定義常量的DLL並取得常量值
- 這使得即使重新修改並導出DLL文件也不會影響到應用程序裡嵌入的常量值
- 應用程序必須重新打包一次、重新嵌入一次常量才可以更新常量值
-
IL_0000: nop IL_0001: ldstr "Max Entries supported in list: " IL_0006: ldc.i4 0x3e8 IL_000b: stloc.0 IL_000c: ldloca.s V_0 IL_000e: call instance string [mscorlib]System.Int32::ToString() IL_0013: call string [mscorlib]System.String::Concat(string, string) IL_0018: call void [mscorlib]System.Console::WriteLine(string)
-
參考書目
- 《CLR via C#》(第4版) Jeffrey Richter