Question

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!
Was it helpful?

Solution

When using the [Flags] attribute you should explicitly map the enum values to integer that contain non overlapping bit patterns. That is, each enum value should be mapped to a power of two:

[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.

Enum.HasFlags checks if the bit field or bit fields that are set in the parameter are also all set in the tested enum. 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). However 0 does not contain the bits set in 1 when testing the other way around.

OTHER TIPS

It returns true because you implemented Editions incorrectly. You must explicitly set the values when you use the [Flags] attribute.

[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)

[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)


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. If you are trying to use flags to make testing enum values easier just use a switch statement instead

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
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top