标记没有2次幂的枚举

本文关键字:枚举 2次 | 更新日期: 2023-09-27 18:06:15

Flag属性的MSDN文档说您应该:

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

…当然,我总是努力记住这样做。然而,没有什么强制的,如果你只是以"基本"的方式创建一个枚举,比如…

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

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

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

标记没有2次幂的枚举

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

[Flags]
public enum FilePermissions
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4,
    ReadWrite = 3, // Read | Write,
    ReadWriteExecute = 7 // Read | Write | Execute
}

可能是因为需要支持这样的情况,这就是为什么编译器不引起警告或错误。

我自己从来没有尝试过,但是也许你可以为FxCop编写一个自定义规则。

检查FxCop和代码分析:编写自己的自定义规则

正如Jacob所说,使用混合的旗帜是很有用的…但也许你可以以某种方式表明这一点,这样你的检测就不会介意了。

编写一个单元测试,遍历用[Flags]装饰的程序集中的每个enum,检查是否有一个值为0(可能确保它被称为NoneDefault),并且每个其他定义的值(来自Enum.GetValues())都是2的幂。您可以使用if ((x & (x - 1)) == 0)检查。

你可能有像属性[Combination]这样的东西来指示被设计为组合的值…它们甚至可以表明它们是什么标志名的组合,所以你也可以检查。

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