标记枚举没有两个值的幂

时间:2011-08-20 05:48:45

标签: c# enums code-analysis static-analysis

Flag属性的MSDN documentation表示您应该:

  

定义2的幂的枚举常数,即1,2,4,8,   等等。这意味着组合枚举中的各个标志   常数不重叠。

......当然,我总是试着记住这样做。但是,没有任何强制执行,如果你只是创建一个枚举'基本'的方式,如...

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

......它的行为不会像预期的那样。为了解决这个问题,我正在寻找某种静态代码分析(如FxCop),当我的代码中存在类似上面的枚举时,它可以发出警告。我能找到的最接近的警告是“CA1008: Enums should have zero value” - 这对于正确设计标志枚举也很有用,但还不够。

在我的代码中找到设计错误的标记枚举的最佳方法是什么?解决方案越自动化越好。

3 个答案:

答案 0 :(得分:3)

有时你想要一个代表多个选项的标志枚举;在这种情况下,这不是一个错误。这是一个常见的例子:

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

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

也许是因为需要支持这样的案例,这就是编译器不会引起警告或错误的原因。

答案 1 :(得分:3)

我自己从未尝试过,但也许您可以为FxCop编写自定义规则。

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

答案 2 :(得分:2)

正如雅各布所说,拥有旗帜的混合物会很有用......但是你可能会以某种方式表明你的侦测并不介意。

编写一个单元测试应该不会太难,该单元测试遍历装饰有[Flags]的程序集中的每个枚举,并检查是否有0的值(可能确保它被称为None或{ {1}})并且每个其他定义的值(来自Default)都是2的幂。您可以使用Enum.GetValues()

进行检查

您可能会有类似属性if ((x & (x - 1)) == 0)的内容来指示设计为组合的值......它们甚至可以指出它们的组合所在的标志名称,因此您也可以检查它们

我知道这不如编译时检查那么好,但假设你已经定期运行测试,那就非常接近了。