Check if a bitmask consists of multiple flags

1.4k Views Asked by At

Note, this is not a dupe of this question:

Testing if a bitmask has one and only one flag

I need to validate whether or not a bitmask consists of multiple flags. I've come up with this method, but I don't like it a whole lot because of the enumeration and casting.

[Flags]
enum MyFlags { a = 1, b = 2, c = 4, d = 8 }

var flags = Enum.GetValues(typeof(MyFlags)).Cast<MyFlags>();

Console.WriteLine(flags.Any(f => f == (MyFlags.a | MyFlags.c))); //false
Console.WriteLine(flags.Any(f => f == MyFlags.b)); //true
1

There are 1 best solutions below

2
On

If what you want is to test if a bitmask consist of flags, you can do it like this

MyFlags flag = MyFlags.b | MyFlags.d | MyFlags.a;

Console.WriteLine(flag.HasFlag(MyFlags.b));             // true
Console.WriteLine(flag.HasFlag(MyFlags.a | MyFlags.b)); // true
Console.WriteLine(flag.HasFlag(MyFlags.c | MyFlags.b)); // false

Edit
You can also have a look at the BitArray class
https://msdn.microsoft.com/en-us/library/system.collections.bitarray(v=vs.110).aspx

Basically you just have to count the number of bit set to one in the BitArray

You can use this fast GetCardinality method to count them (alternatively, you can also do it with a for loop): Counting bits set in a .Net BitArray Class. Then:

public static bool HasExactlyOneBitSet(Enum e)
{
    return GetCardinality(new BitArray(new[] { (int)(object)e })) == 1;
}

And you will use it like this:

HasExactlyOneBitSet(MyFlags.A);             // true
HasExactlyOneBitSet(MyFlags.A | MyFlags.C); // false