【问题标题】:What is Enum.HasFlag supposed to return?Enum.HasFlag 应该返回什么?
【发布时间】:2013-11-18 20:45:26
【问题描述】:

我有枚举:

[Flags]
enum Editions
{
    Educational,
    Basic,
    Pro,
    Ultra
}

为什么会出现这种行为?

var x = Editions.Basic;
var y = Editions.Educational;
var test =x.HasFlag(y); // why is this true!?
// and!!!
var test2 = y.HasFlag(x); // this is false!

【问题讨论】:

  • Flags 属性应该与枚举一起使用,其中每个值对应一个单独的位。你使用它的方式并没有真正的意义,所以不仅仅是HasFlag 会产生令人困惑的结果。
  • MSDN FlagsAttribute 告诉你如何使用属性。

标签: c# enums flags


【解决方案1】:

使用[Flags] 属性时,您应该将枚举值显式映射到包含非重叠位模式的整数。也就是说,每个枚举值都应该映射到 2 的幂:

[Flags]
enum Editions
{
    Educational = 1,
    Basic = 2,
    Pro = 4,
    Ultra = 8
}

如果没有显式编号,Educational 将映射为 0,Basic 将映射为 1。

Enum.HasFlags 检查参数中设置的位域或位域是否也都设置在测试的枚举中。在您的情况下,x 是 1,y 是 0。这意味着 x 包含在 0 中设置的所有位(根本没有位)。然而,0 不包含在1 中设置的位,而反过来测试时。

【讨论】:

  • 这表明Editions.Educational | Editions.Basic 是有道理的。我认为这些枚举值更有可能不应该是标志,Flags 属性也应该被删除。
【解决方案2】:

它返回 true 是因为您错误地实现了 Editions。使用 [Flags] 属性时必须显式设置值。

[Flags]
enum Editions
{                         //binary format
    Educational = 1 << 0, // 0001
    Basic  = 1 << 1,      // 0010
    Pro  = 1 << 2,        // 0100
    Ultra  = 1 << 3       // 1000
}

如果您不分配数字,它将自动从 0 开始为每个选项分配 1(这是标准的 enum 行为,添加 [Flags] 属性不会改变此行为)

[Flags]
enum Editions
{                    //binary format
    Educational = 0, // 0000
    Basic  = 1,      // 0001
    Pro  = 2,        // 0010
    Ultra  = 3       // 0011
}

所以您所做的两个测试是:0001 设置了标志 0000(这是真的,您没有测试任何标志)和 0000 设置了标志 0001(这绝对是错误的)


但是看看你的名字,我怀疑你是否应该使用 [Flags],因为我怀疑你所做的任何事情都可以同时是 BasicPro。如果您尝试使用标志来简化枚举值的测试,请改用 switch 语句

Editions edition = GetEdition();

switch(edition)
{
    case Editions.Basic:
         DoSomthingSpecialForBasic();
         break;

    case Editions.Pro:
    case Editions.Ultra:
        DoSomthingSpecialForProAndUltra();
        break;

    //Does not do anything if Editions.Educational
}

【讨论】:

    猜你喜欢
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 2017-12-12
    • 2011-03-09
    相关资源
    最近更新 更多