2013-04-25 26 views
6

Tôi có cờ enum sau:C# Enums - Kiểm tra Flags chống lại một Mask

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

Bây giờ tôi có một thể hiện enum mà tôi cần phải kiểm tra xem nó có thể đọc được. Nếu tôi sử dụng mã sau:

myMemoryProtection.HasFlag(MemoryProtection.Readable) 

Nó luôn trả về false trong trường hợp của tôi vì tôi nghĩ HasFlag sẽ kiểm tra xem nó có gắn cờ hay không. Tôi cần một cái gì đó thanh lịch để tránh làm điều này:

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

Tôi có thể làm như thế nào?

+0

Yêu cầu .NET 4.0 hoặc cao hơn – linquize

Trả lời

7

Bạn có thể bật điều kiện xung quanh, và kiểm tra xem hỗn enum có cờ, chứ không phải là kiểm tra cờ cho composite, như thế này:

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

Dưới đây là một ví dụ:

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

In này Readable.

+0

Độc giả nên lưu ý rằng 'HasFlag' trở thành có sẵn với .NET 4.0. – Grinn

+0

Đối với các mặt nạ không có bit mặt nạ, đây sẽ là cách tiếp cận tốt – GoldBishop

3

Cố gắng khai thác Bitwise:

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

Đây là phương pháp ưu tiên nếu bạn đã triển khai phương pháp tiếp cận bit-mask. – GoldBishop

3

Vâng, hasFlag kiểm tra nếu mỗi bit lĩnh vực (cờ) được thiết lập.

Thay vì xử lý Readable làm tổng hợp tất cả các biện pháp bảo vệ bao gồm Read trong tên, bạn có thể chuyển thành phần đó không? Ví dụ.

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

Sau đó, bạn có thể viết mã như:

myMemoryProtection.HasFlag(MemoryProtection.Read) 
Các vấn đề liên quan