2012-10-03 48 views
13

想象一下這個枚舉在一個DLL中。添加枚舉值會破壞二進制兼容性嗎?

public enum Colors 
{ 
    Red, 
    Green 
} 

是否添加枚舉值會破壞二進制兼容性?如果我要改變它,現有的EXE會破壞嗎?

public enum Colors 
{ 
    Red, 
    Green, 
    Blue 
} 

我看到this answer,但它似乎解決插入值的情況。如果我將值添加到最後只有,那可以嗎?

回答

17

不,這不會破壞二進制兼容性(儘可能:程序集仍然會加載等),因爲枚舉基本上是整型文字常量。在中間插入值顯然是一個非常危險的想法,但您已經排除了這一點。

但是,它可能會導致一些你需要警惕的其他問題:

  • 一些代碼(switch報表尤其是)可能沒有預料到的新值;技術上,這是之前太問題,因爲枚舉不是價值的檢查(枚舉變量可以包含未定義的值)
  • 任何查詢可用的枚舉是會得到不同的結果 特別
    • ,序列化和反序列化可能會失敗不料,如果有使用枚舉那些尚未被特定的客戶端
+1

太棒了。我能做些什麼來抵制破損?顯然,如果我按照自己的方式行事,我不會追加枚舉,但是考慮到情況,處理這個問題的最安全方法是什麼?在switch語句(雙關意外)的情況下,是否指定了'default:'槽以防止更改? – TheBuzzSaw

+1

@TheBuzzSaw抵制破壞的最好方法是不要將枚舉用於任何你希望在時間結束前不會保持不變的東西。 – Servy

+0

@Servy同意...但由於我現在被enums卡住了,你還有什麼? ;) – TheBuzzSaw

3

應該沒事預期,假設你只追加到年底的數據。但是,破壞的風險來自枚舉值是隱式定義的,從0開始。因此,如果有人將這些值保存到數據庫中,則可能會更改它們映射的值。

舉個例子,如果你改變了你的枚舉是:

public enum Colors 
{ 
    Blue, 
    Red, 
    Green 
} 

任何人誰在自己的DB中存儲這些值會看到的東西,曾經紅,現在是藍的,什麼是綠色,現在是紅。

理想情況下,你應該定義你的枚舉,如下所示:

public enum Colors 
{ 
    Red = 0, 
    Green = 1 
} 

然後,當你添加一個新的,你應該有:

public enum Colors 
{ 
    Red = 0, 
    Green = 1, 
    Blue = 2 
} 

這將有助於防止任何潛在的版本問題。

+0

+1。如果可以的話,我也會給這個綠色支票。這是使枚舉更加堅固的巧妙方法。 – TheBuzzSaw

+0

請注意,規範明確指出,如果您未指定任何值,則它將從0開始,併爲每個值遞增1,因此不像第一種情況下的後備整數是未定義的行爲。你可以添加到最後。 – Servy

+0

沒錯,但是你必須把它添加到最後,否則就會崩潰。 –