標籤:
查看微軟的C#參考中enum介紹的時候,冒出來下面一段: 可靠編程 與任何常量一樣,對枚舉中各個值的所有引用在編譯時間均將轉換為數值文本。 這可形成潛在的版本控制問題,如常量(C# 編程指南)中所述。
給新版本的枚舉賦其他值,或者更改新版本中枚舉成員的值,可導致相關原始碼出現問題。 通常在 switch 語句中使用枚舉值。 如果 enum 類型中添加了其他元素,則 switch 語句的預設節可能被意外選定。
如果其他開發人員使用您的代碼,則需要提供相關說明,告訴開發人員如果任何 enum 類型中添加了新元素,他們的代碼應該如何響應。
這是什麼鬼??
仔細琢磨琢磨,可能存在下面這種情況:
一個程式集A中,定義了一些常量:
public const int TableA = 1; public const int TableB = 3; public const int TableE = 4;
這些常量在另一個程式集B中被引用:
switch (iTable) { // TableA case TableA: dosomething(); break; // TableB case TableB: dosomething(); break; // TableE case TableE: dosomething(); break; // 預設 default: dosomething(); break; }
這段代碼通過變數iTable對不同Table作不同處理。
到現在一切很好,沒什麼問題。
有一天可能有些需求變動或某人純粹出於不爽,把程式集A變動了一下,如下:
public const int TableA = 1;public const int TableB = 2;public const int TableC = 3;public const int TableD = 4;public const int TableE = 5;
編譯過後,直接替換了程式集B項目中需要的程式集A的*.dll,運行一下,沒有報錯。嘿!一切OK!!
我們回頭看看這一句:與任何常量一樣,對枚舉中各個值的所有引用在編譯時間均將轉換為數值文本。
這是什麼意思??
其實就是這個意思,程式集B編譯後的代碼等效於如下代碼:
switch (iTable) { // TableA case 1: dosomething(); break; // TableB case 2: dosomething(); break; // TableE case 5: dosomething(); break; // 預設 default: dosomething(); break; }
這時,問題就來了:
- iTable為TableA值的時候,沒錯,程式進入case 1;
- iTable為TableB值的時候,程式進入default;(為什嗎?因為TableB 的值被改為 2 了,沒有這個分支。)
- iTable為TableE值的時候,程式還是進入default;(理由與TableB一樣。)
這就是C#參考裡那一段要表達的真正含義。解決這個問題也簡單:程式集B項目引用的dll檔案有更新的時候,最好重新編譯一下。
重新編譯後的程式集B等效如下代碼:
switch (iTable) { // TableA case 1: dosomething(); break; // TableB case 2: dosomething(); break; // TableE case 5: dosomething(); break; // 預設 default: dosomething(); break; }
這樣,一切才真正OK了!!
(純理論研究,沒有測試。一切不良後果,概不負責!)
C#中 enum 和 常量 的可靠編程