Flag
属性的MSDN documentation表示您应该:
定义2的幂的枚举常数,即1,2,4,8, 等等。这意味着组合枚举中的各个标志 常数不重叠。
......当然,我总是试着记住这样做。但是,没有任何强制执行,如果你只是创建一个枚举'基本'的方式,如...
[Flags]
public enum BrokenEnum
{
None,
FirstOption,
SecondOption,
ThirdOption
}
......它的行为不会像预期的那样。为了解决这个问题,我正在寻找某种静态代码分析(如FxCop),当我的代码中存在类似上面的枚举时,它可以发出警告。我能找到的最接近的警告是“CA1008: Enums should have zero value” - 这对于正确设计标志枚举也很有用,但还不够。
在我的代码中找到设计错误的标记枚举的最佳方法是什么?解决方案越自动化越好。
答案 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编写自定义规则。
答案 2 :(得分:2)
正如雅各布所说,拥有旗帜的混合物会很有用......但是你可能会以某种方式表明你的侦测并不介意。
编写一个单元测试应该不会太难,该单元测试遍历装饰有[Flags]
的程序集中的每个枚举,并检查是否有0的值(可能确保它被称为None
或{ {1}})并且每个其他定义的值(来自Default
)都是2的幂。您可以使用Enum.GetValues()
。
您可能会有类似属性if ((x & (x - 1)) == 0)
的内容来指示设计为组合的值......它们甚至可以指出它们的组合所在的标志名称,因此您也可以检查它们
我知道这不如编译时检查那么好,但假设你已经定期运行测试,那就非常接近了。