2010-03-09 40 views
12

Tôi đã có một Enum đánh dấu bằng [Flags] thuộc tính như sau:Làm cách nào để xác định xem giá trị Enum có một hoặc nhiều giá trị được so sánh với?

[Flags] 
public enum Tag : int 
{ 
    None = 0, 
    PrimaryNav = 1, 
    HideChildPages = 2, 
    HomePage = 4, 
    FooterLink = 8 
} 

On sitemapnodes trong sitemap tôi lưu trữ các giá trị int cho sự kết hợp thẻ như một thuộc tính.

Điều tôi cần làm là kiểm tra xem nút có bất kỳ một nào của một hoặc nhiều thẻ, ví dụ: Tag.PrimaryNav | Tag.HomePage.

Tôi đang gặp khó khăn với logic boolean cần thiết để xác định xem giá trị Enum có một hoặc nhiều giá trị được so sánh với.

Xin lỗi nếu điều này không rõ ràng. Tôi có thể cung cấp thêm thông tin nếu cần.

Trả lời

26

Bạn có thể làm điều đó bằng cách kết hợp các giá trị với | và kiểm tra qua &.

Để kiểm tra xem giá trị chứa hoặc các thẻ:

if ((myValue & (Tag.PrimaryNav | Tag.HomePage)) != 0) { ... } 

Các | kết hợp enums bạn đang thử nghiệm (bitwise) và & kiểm tra qua Bitwise mặt nạ - nếu kết quả isn' t số không, nó có ít nhất một trong số chúng được thiết lập.

Nếu bạn muốn kiểm tra xem nó có cả của họ được thiết lập, bạn có thể làm điều đó cũng như:

Tag desiredValue = Tag.PrimaryNav | Tag.HomePage; 
if ((myValue & desiredValue) == desiredValue) { ... } 

Ở đây chúng ta đang che đi bất cứ điều gì chúng ta không quan tâm đến, và việc kiểm thử giá trị kết quả bằng số chúng tôi làm quan tâm (chúng tôi không thể sử dụng != 0 như trước đây vì điều đó sẽ khớp với hoặc giá trị và tại đây chúng tôi quan tâm đến cả hai).

Một số liên kết:

+0

Câu trả lời tuyệt vời, cảm ơn rất nhiều :) –

1
var someEnumValue = Tag.PrimaryNav | Tag.HomePage; 

Để kiểm tra nếu enum chứa một giá trị nhất định:

if ((someEnumValue & Tag.PrimaryNav) == Tag.PrimaryNav) 
{ 

} 
1
var tag = Tag.HideChildPages | Tag.PrimaryNav; 

If ((tag & Tag.PrimaryNav) == Tag.PrimaryNav) { 
    // Tag.PrimaryNav set. 
} 
2

Đối Bitwise (Flags) enums, một "bất kỳ" kiểm tra là!= 0, vì vậy:

const Tag flagsToLookFor = Tag.PrimaryNav | Tag.HomePage; 
if ((node.Tag & flagsToLookFor) != 0) { 
    // has some cross-over with PrimaryNav or HomePage (and possibly others too) 
} 
+0

Tương tự như vậy, điều này đã làm các trick - cảm ơn Marc. –

9

Bạn có thể sử dụng phương pháp HasFlag để tránh sự cần thiết của logic boolean,

Tag Val = (Tag)9; 

if (Val.HasFlag(Tag.PrimaryNav)) 
{ 
    Console.WriteLine("Primary Nav"); 
} 

if(Val.HasFlag(Tag.HomePage)) 
{ 
    Console.WriteLine("Home Page"); 
} 
+1

Phương pháp này là mới trong .NET 4.0, do đó, nó sẽ không hoạt động nếu OP đang sử dụng phiên bản cũ hơn ... –

+0

yea sau đó sử dụng bất kỳ danh sách phương pháp nào khác chỉ muốn ném nó ra khỏi đó. – rerun

+0

+1 Một điểm rất tốt. –

1

Bạn có thể sử dụng Unconstrained Melody thư viện Jon Skeet:

var someEnumValue = Tag.PrimaryNav | Tag.HideChildPages; 
someEnumValue.HasAny(Tag.PrimaryNav | Tag.HomePage); // Returns true 
0

Bạn có thể sử dụng phương pháp mở rộng này trên enum, đối với bất kỳ loại enums nào:

public static bool IsSingle(this Enum value) 
    { 
     var items = Enum.GetValues(value.GetType()); 
     var counter = 0; 
     foreach (var item in items) 
     { 
      if (value.HasFlag((Enum)item)) 
      { 
       counter++; 
      } 
      if (counter > 1) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 
Các vấn đề liên quan