2011-08-20 53 views
6

MSDN documentationFlag屬性的電源標誌枚舉說,你應該:沒有兩個值

定義枚舉常數的兩個大國,也就是1,2,4,8, 等。這意味着組合枚舉 常量中的各個標誌不會重疊。

...當然,我總是試圖記住這樣做。然而,沒有任何強制執行,如果你只是創建一個枚舉的「基本」的方式像...

[Flags] 
public enum BrokenEnum 
{ 
    None, 
    FirstOption, 
    SecondOption, 
    ThirdOption 
} 

...如預期不會做人。爲了解決這個問題,我正在尋找某種類型的靜態代碼分析(如FxCop),當我的代碼中存在像上面這樣的枚舉時,可以發出警告。我能找到的最接近的這種警告是'CA1008: Enums should have zero value' - 這對設計正確的枚舉標誌也很有幫助,但還不夠。

什麼是在我的代碼中查找錯誤設計的標誌枚舉的最佳方法?解決方案越自動化越好。

回答

2

正如雅各布所說,混合標誌可能是有用的......但可能你可能會指出,以便你的檢測不介意。

它不應該是太難寫一個單元測試,其經過在裝飾有[Flags]和檢查的組件的每個枚舉那有一個爲0(可能確保它被稱爲NoneDefault)的值,並且,每一個其它定義的值(從Enum.GetValues())是兩個冪。您可以使用if ((x & (x - 1)) == 0)進行檢查。

你可能會有類似[Combination]這樣的屬性來指示設計爲組合的值......他們甚至可以指出它們是什麼標誌名稱的組合,所以你也可以檢查它們。

我知道這不像編譯時檢查,但假設你已經定期運行測試,它非常接近。

+1

我想我不應該一直在思考靜態代碼分析的「盒子裏面」。像這樣的單元測試應該很容易,並且給我幾乎相同的最終結果。 –

3

有時候你想要一個表示多個選項的標誌枚舉;在這種情況下,這不是一個錯誤。這裏有一個常見的例子:

[Flags] 
public enum FilePermissions 
{ 
    None = 0, 
    Read = 1, 
    Write = 2, 
    Execute = 4, 

    ReadWrite = 3, // Read | Write, 
    ReadWriteExecute = 7 // Read | Write | Execute 
} 

或許是因爲需要支持的情況下這樣的,這就是爲什麼編譯器不會導致警告或錯誤。

+0

我可以看到爲什麼編譯器不這麼做的原因(也考慮向後兼容性,不合理的複雜性等),所以我很好,你沒有得到編譯器警告。但我仍在尋找一種被警告的方法。在像你這樣的情況下,這種使用是有效的,你可以使用'SuppressMessage'屬性來禁用檢查。 –

+0

你也可以有更詳細的標誌。例如'{View = 1,Alter = 2,Action = 4 |查看| Alter}':這樣就可以操作一個你需要View和Alter的項目;除了權利本​​身。 –

3

我從來沒有嘗試過,但也許你可以爲FxCop編寫一個自定義規則。

檢查FxCop and Code Analysis: Writing Your Own Custom Rules

+0

謝謝,這似乎很有希望。我可能會堅持Jon Skeet的回答,因爲我認爲在短期內編寫單元測試會更快,而不是學習如何編寫自定義FxCop規則。 –