标记枚举没有两个值的幂

Ste*_*iel 6 c# enums code-analysis static-analysis

MSDN文档Flag属性,说,你应该:

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

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

[Flags]
public enum BrokenEnum
{
    None,
    FirstOption,
    SecondOption,
    ThirdOption
}
Run Code Online (Sandbox Code Playgroud)

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

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

Jac*_*cob 5

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

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

    ReadWrite = 3, // Read | Write,
    ReadWriteExecute = 7 // Read | Write | Execute
}
Run Code Online (Sandbox Code Playgroud)

也许是因为需要支持这样的情况,这就是编译器不会导致警告或错误的原因。


Jon*_*eet 2

正如雅各布所说,混合使用标志可能会很有用......但您可能可以以某种方式表明这一点,以便您的检测不介意。

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

您可能有类似属性的东西[Combination]来指示被设计为组合的值...它们甚至可以指示它们应该是哪些标志名称的组合,因此您也可以检查这一点。

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