代码之家  ›  专栏  ›  技术社区  ›  Tommaso Belluzzo

C#枚举-针对掩码检查标志

  •  8
  • Tommaso Belluzzo  · 技术社区  · 13 年前

    我有以下枚举标志:

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

    我该怎么做?

    3 回复  |  直到 13 年前
        1
  •  10
  •   Sergey Kalinichenko    13 年前

    你可以扭转局面,检查复合材料 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 .

        2
  •  4
  •   dan radu    13 年前

    尝试按位运算符:

    [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);
    }
    
        3
  •  4
  •   Josh Milthorpe    13 年前

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

    而不是治疗 Readable 作为所有保护措施的组合,包括 Read 在名字里,你能把作文改过来吗?例如。

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