什么是Enum.HasFlag应该返回?

Ton*_*Nam 1 c# enums flags

我有枚举:

[Flags]
enum Editions
{
    Educational,
    Basic,
    Pro,
    Ultra
}
Run Code Online (Sandbox Code Playgroud)

为什么我会这样做?

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!
Run Code Online (Sandbox Code Playgroud)

And*_*bel 12

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

[Flags]
enum Editions
{
    Educational = 1,
    Basic = 2,
    Pro = 4,
    Ultra = 8
}
Run Code Online (Sandbox Code Playgroud)

没有显式编号,Educational将映射到0和Basic1.

Enum.HasFlags检查参数中设置的位字段或位字段是否也在测试的枚举中设置.在你的情况下,x是1并且y是0.这意味着它x包含所有设置的位0(根本就没有位).但是0,1在测试相反方式时不包含设置的位.

  • 这表明`Editions.Education | Editions.Basic`是有道理的.我认为这些枚举值更可能不应该是标志,并且"Flags"属性也应该被删除. (3认同)

Sco*_*ain 6

它返回true,因为您实现Editions不正确.您必须在使用该[Flags]属性时显式设置值.

[Flags]
enum Editions
{                         //binary format
    Educational = 1 << 0, // 0001
    Basic  = 1 << 1,      // 0010
    Pro  = 1 << 2,        // 0100
    Ultra  = 1 << 3       // 1000
}
Run Code Online (Sandbox Code Playgroud)

如果你没有指定数字,它会自动指定它们从0开始,每个选项后面加1(这是标准enum行为,添加[Flags]属性不会改变这种行为)

[Flags]
enum Editions
{                    //binary format
    Educational = 0, // 0000
    Basic  = 1,      // 0001
    Pro  = 2,        // 0010
    Ultra  = 3       // 0011
}
Run Code Online (Sandbox Code Playgroud)

所以你做的两个测试是:设置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
}
Run Code Online (Sandbox Code Playgroud)