C# Enums - Check Flags against a Mask
11,781
Solution 1
You can turn the condition around, and check if the composite enum
has the flag, rather than checking the flag for the composite, like this:
if (MemoryProtection.Readable.HasFlag(myMemoryProtection)) {
...
}
Here is an example:
MemoryProtection a = MemoryProtection.ExecuteRead;
if (MemoryProtection.Readable.HasFlag(a)) {
Console.WriteLine("Readable");
}
if (MemoryProtection.Writable.HasFlag(a)) {
Console.WriteLine("Writable");
}
This prints Readable
.
Solution 2
Try bitwise operators:
[TestMethod]
public void FlagsTest()
{
MemoryProtection mp = MemoryProtection.ReadOnly | MemoryProtection.ReadWrite | MemoryProtection.ExecuteRead | MemoryProtection.ExecuteReadWrite;
MemoryProtection value = MemoryProtection.Readable | MemoryProtection.Writable;
Assert.IsTrue((value & mp) == mp);
}
Solution 3
Yes, hasFlag
checks if every bit field (flag) is set.
Rather than treating Readable
as a composite of all the protections that include Read
in the name, can you turn the composition around? E.g.
[Flags]
private enum MemoryProtection: uint
{
NoAccess = 0x000,
Read = 0x001,
Write = 0x002,
Execute = 0x004,
Copy = 0x008,
Guard = 0x010,
NoCache = 0x020,
ReadOnly = Read,
ReadWrite = (Read | Write),
WriteCopy = (Write | Copy),
// etc.
NoAccess = 0x800
}
Then you can write code like:
myMemoryProtection.HasFlag(MemoryProtection.Read)
Author by
Tommaso Belluzzo
Updated on June 14, 2022Comments
-
Tommaso Belluzzo almost 2 years
I have the following enum flags:
[Flags] private enum MemoryProtection: uint { None = 0x000, NoAccess = 0x001, ReadOnly = 0x002, ReadWrite = 0x004, WriteCopy = 0x008, Execute = 0x010, ExecuteRead = 0x020, ExecuteReadWrite = 0x040, ExecuteWriteCopy = 0x080, Guard = 0x100, NoCache = 0x200, WriteCombine = 0x400, Readable = (ReadOnly | ReadWrite | ExecuteRead | ExecuteReadWrite), Writable = (ReadWrite | WriteCopy | ExecuteReadWrite | ExecuteWriteCopy) }
Now i have an enum instance that I need to check if it's readable. If I use the following code:
myMemoryProtection.HasFlag(MemoryProtection.Readable)
It always returns false in my case because I think HasFlag check if it has every flag. I need something elegant to avoid doing this:
myMemoryProtection.HasFlag(MemoryProtection.ReadOnly) || myMemoryProtection.HasFlag(MemoryProtection.ReadWrite) || myMemoryProtection.HasFlag(MemoryProtection.ExecuteRead) || myMemoryProtection.HasFlag(MemoryProtection.ExecuteReadWrite)
How can I do it?
-
Grinn about 9 yearsReaders should note that
HasFlag
became available with .NET 4.0. -
GoldBishop over 6 yearsThis is the preferred method if you have implemented a bit-mask approach.