2011-08-20 51 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规则。 –