Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HasFlags always returns true for None (0) value in enum

This is the enum definition:

[Flags]
enum Animals
{
    None = 0,
    Dog = 1,
    Cat = 2,
    Horse = 4,
    Zebra = 8,
}

Now, given the following code, why does the HasFlag method return true for the value Animals.None?

Animals myAnimals = Animals.Dog | Animals.Horse;

var hasNone = myAnimals.HasFlag(Animals.None);    //true! Why?
var hasCat = myAnimals.HasFlag(Animals.Cat);      //false
var hasDog = myAnimals.HasFlag(Animals.Dog);      //true
var hasHorse = myAnimals.HasFlag(Animals.Horse);  //true
var hasZebra = myAnimals.HasFlag(Animals.Zebra);  //false
like image 506
Henrik Söderlund Avatar asked Mar 15 '13 15:03

Henrik Söderlund


3 Answers

HasFlag is effectively this:

HasFlag = (GivenFlag & Value) == GivenFlag;

//"Anything" AND 0 == 0  --> always true
like image 158
Austin Salonen Avatar answered Nov 20 '22 16:11

Austin Salonen


I've come up against this before myself. It's by design in the .NET Framework:

If the underlying value of flag is zero, the method returns true. If this behavior is not desirable, you can use the Equals method to test for equality with zero and call HasFlag only if the underlying value of flag is non-zero, as the following example illustrates.

You can read a little more about this here.

like image 20
Martin Avatar answered Nov 20 '22 16:11

Martin


There is already a plethora of answers describing WHY this happens, so I will just add that what you can do to get what you're looking for is to not use HasFlag in that case, but instead do var hasNone = myAnimals == Animals.None.

I personally really loathe extension methods, but it would be possible to put this in an extension on Enum if you really value being able to just write myOptionEnum.HasNoFlags(). I would just run with explicitly checking for the None value in this special case though.

like image 2
sara Avatar answered Nov 20 '22 17:11

sara