定义枚举标志值的惯例是什么?

时间:2014-05-16 15:51:27

标签: c# enum-flags

假设我有以下代码:

[Flags]
enum MyFlags
{
    None = 0,
    A = 1,
    B = 2,
    C = 4,
    D = 8,
    E = 16,
    // ...
}

当标志数量增长非常大时,这显然不是最佳选择。并且通过最佳,平均可读,不快速或节省内存。

对于组合标志,例如

AB = 3

我们可以轻松使用

AB = A | B
相反,它更具可读性 并用于组合所有标志

All = A | B | C | ...

使用

会更有利
All = ~None
相反,即使我们没有充分利用所有可用的32/64位。

但是常规价值呢?

之间

E = 16
E = 0b10000
E = 0x10
E = 1 << 4

或其他我没有想过的方法,哪种方式最适合大量的旗帜?

或者换句话说,在C#中设置标志值的(商定的)惯例是什么?

让我们假设为了论证,值不会对齐,所以代码可能看起来像这样

None = 0,
Apple = 1,
Banana = 2,
StrangeFruit = Apple | Banana,
Cherry = 4,
Date = 8,
Elderberry = 16,
// ...

2 个答案:

答案 0 :(得分:7)

对于常规值,我喜欢1 << n:在你花了很短的时间来理解它之后,很容易看出发生了什么,很难搞乱,并且不需要十六进制/二进制转换/思维。

[Flags]
enum MyFlags
{
    None = 0,
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    // ...
    Lastly = 1 << 31,
}

就实际的定义的约定而言,我认为不存在。 MS的Enum Design指南说明了

  

√DO对标志枚举值使用2的幂,以便可以使用按位OR运算自由组合。

但没有指定如何在源代码中编写它(这些是与语言无关的指导原则; C#中可能有用的东西甚至可能不适用于另一种.Net语言)。

答案 1 :(得分:1)

我认为没有任何既定惯例。您可以参考Cwalina,Abrahms的框架设计指南获取指导。

我更喜欢使用十六进制方法0x00, 0x01。您使用1,2,4,8,然后向左移动到下一个位置。对于通常组合的值,我更喜欢您描述的OR'ing方法。

示例:

[Flags]
public enum Directions
{
    None = 0x00,
    Left = 0x01,
    Right = 0x02,
    Top = 0x04,
    Bottom = 0x08,
    Forward = 0x10,
    Backward = 0x20,
    TopLeft = Top | Left,
    TopRight = Top | Right,
    BottomLeft = Bottom | Left,
    BottomRight = Bottom | Right
}