C#枚举 – 针对面具检查标志

我有以下枚举标志:

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

现在我有一个枚举实例,我需要检查它是否可读。 如果我使用以下代码:

 myMemoryProtection.HasFlag(MemoryProtection.Readable) 

它总是在我的情况下返回false,因为我认为HasFlag检查它是否有每个标志。 我需要优雅的东西来避免这样做:

 myMemoryProtection.HasFlag(MemoryProtection.ReadOnly) || myMemoryProtection.HasFlag(MemoryProtection.ReadWrite) || myMemoryProtection.HasFlag(MemoryProtection.ExecuteRead) || myMemoryProtection.HasFlag(MemoryProtection.ExecuteReadWrite) 

我该怎么做?

你可以改变条件,检查复合enum是否有标志,而不是检查复合的标志,如下所示:

 if (MemoryProtection.Readable.HasFlag(myMemoryProtection)) { ... } 

这是一个例子:

 MemoryProtection a = MemoryProtection.ExecuteRead; if (MemoryProtection.Readable.HasFlag(a)) { Console.WriteLine("Readable"); } if (MemoryProtection.Writable.HasFlag(a)) { Console.WriteLine("Writable"); } 

这打印Readable

是的, hasFlag检查是否设置了每个位字段(标志)。

而不是将Readable视为包含Read in the name的所有保护的组合,你可以改变组合吗? 例如

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

然后你可以编写如下代码:

 myMemoryProtection.HasFlag(MemoryProtection.Read) 

尝试按位运算符:

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