简体   繁体   English

Enum.HasFlag应该返回什么?

[英]What is Enum.HasFlag supposed to return?

I have the enum: 我有枚举:

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

why do I get this behavior? 为什么会出现这种现象?

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!

When using the [Flags] attribute you should explicitly map the enum values to integer that contain non overlapping bit patterns. 使用[Flags]属性时,应将枚举值显式映射到包含非重叠位模式的整数。 That is, each enum value should be mapped to a power of two: 也就是说,每个枚举值都应映射为2的幂:

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

Without the explicit numbering, Educational will be mapped to 0 and Basic to 1. 没有显式编号, Educational将映射为0, Basic将映射为1。

Enum.HasFlags checks if the bit field or bit fields that are set in the parameter are also all set in the tested enum. Enum.HasFlags检查在参数中设置的一个或多个位字段是否也都在测试的枚举中设置了。 In your case, x is 1 and y is 0. That means that x contains all of the bits set in 0 (that is no bits at all). 在您的情况下, x为1, y为0。这意味着x包含设置为0所有位(完全没有位)。 However 0 does not contain the bits set in 1 when testing the other way around. 但是,在进行另一种测试时, 0不包含设置为1的位。

It returns true because you implemented Editions incorrectly. 它返回true,因为您错误地实施了Editions You must explicitly set the values when you use the [Flags] attribute. 使用[Flags]属性时,必须显式设置值。

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

If you do not assign numbers it will auto assign them starting at 0 going up by 1 for each option after that (this is standard enum behavior, adding the [Flags] attribute does not change this behavior) 如果不分配数字,它将自动从0开始分配它们,然后为每个选项enum 1(这是标准enum行为,添加[Flags]属性不会更改此行为)

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

So the two tests you did was: 0001 has the flag 0000 set (which is true, you are not testing for any flags) and 0000 has the flag 0001 set (which is defiantly false) 因此,您进行的两个测试是: 0001设置了标志0000 (这是真的,您没有测试任何标志),而0000设置了标志0001 (绝对是错误的)


However looking at your names I doubt you should be using [Flags] at all because I doubt whatever you are doing can be Basic and be Pro at the same time. 但是,看看您的名字,我怀疑您是否应该使用[Flags] ,因为我怀疑您所做的任何事情都可以同时成为BasicPro If you are trying to use flags to make testing enum values easier just use a switch statement instead 如果您尝试使用标志来简化测试枚举值,则只需使用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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM