2010-09-08 34 views
25

Tôi có một enum được gắn cờ và cần truy xuất tên của tất cả các giá trị được đặt trên đó.Cách hiệu quả nhất để phân tích cú pháp enum được gắn cờ thành danh sách

Tôi hiện đang tận dụng phương thức ToString() của enum trả về các phần tử được phân tách bằng dấu phẩy.

public void SetRoles(Enums.Roles role) 
    { 
     IList<Entities.Role> roleList = role.ToString("G").Split(',') 
      .Select(r => new Entities.Role(r.Trim())) 
      .ToList(); 
    ... 
    } 

Tôi chắc chắn phải có cách tốt hơn.

+0

Tốt để biết rằng một cái gì đó như thế này tồn tại - 'phương thức ToString() của enum trả về các phần tử được phân tách bằng dấu phẩy'. Bạn đã làm ngày của tôi :). +1. – RBT

Trả lời

22

Câu hỏi hay!

Tôi không thể nghĩ ra bất cứ điều gì tốt hơn so với:

public void SetRoles(Enums.Roles role) 
{ 
    List<string> result = new List<string>(); 
    foreach(Roles r in Enum.GetValues(typeof(Roles)) 
    { 
    if ((role & r) != 0) result.Add(r.ToString()); 
    } 
} 
+3

Thay thế tốt hơn '(vai trò & r)! = 0' bằng' (vai trò & r) == r' hoặc 'vai trò.HasFlag (r)' trong .net4. Và chắc chắn rằng bạn chỉ định các giá trị có sức mạnh là 2, nếu không nó sẽ thất bại. Xem http://stackoverflow.com/questions/8447/enum-flags-attribute –

+8

Đây là phiên bản một dòng giống nhau: 'Enum.GetValues ​​(typeof (Vai trò)). Cast () .Where (r => (role & r) == r) .Chọn (r => r.ToString()) ' – Ondra

+2

Ngoài ra, thay vì nếu ((vai trò & r)! = 0) sử dụng role.HasFlag (r) – dlchambers

3

Tại sao bạn cần danh sách? Tất cả mọi thứ đã được lưu trữ trong những lá cờ:

[Flags] 
enum Roles 
{ 
    Read = 0x1, 
    Write = 0x2, 
    Delete = 0x4, 
} 

Sau đó gán vai trò:

var roles = Roles.Read | Roles.Write; 

Và bất cứ khi nào bạn cần phải kiểm tra xem một vai trò nhất định đã được bạn không cần phải nhìn vào một danh sách, nhưng chỉ cần nhìn vào liệt kê vai trò:

if ((roles & Roles.Read) == Roles.Read) 
{ 
    // The user has read permission 
} 
if ((roles & Roles.Write) == Roles.Write) 
{ 
    // The user has write permission 
} 
+2

Đó là cách ứng dụng đang sử dụng nó. Tuy nhiên, đây là một mối quan tâm dai dẳng hơn. Tôi thà bỏ phương pháp này không biết giá trị của enum có thể chứa. –

+3

Nếu nó là để kiên trì tất cả những gì bạn cần lưu trữ là một số nguyên đại diện cho các cờ vì số nguyên này cho phép bạn trích xuất tất cả các vai trò sau này. Không cần phải lưu trữ danh sách. Nếu không, '[Flags]' là loại không cần thiết nếu bạn định giữ danh sách các vai trò. Bạn cũng sẽ nhận được một vài byte phương tiện lưu trữ :-) –

+1

Tuy nhiên, đôi khi điều quan trọng là giữ cho dữ liệu được lưu trữ ở định dạng có thể đọc được một phần nào đó. Trong trường hợp đó, Enum.Parse có thể xử lý các giá trị enum liên kết tốt, tương tự như cách ToString() xuất ra chúng. Vì vậy, 'Enum.Parse (typeof (Vai trò)," Đọc, Viết ")' sẽ cho kết quả Đọc chính xác | Viết giá trị. Trên thực tế tôi sẽ viết một câu trả lời với thông tin này. –

7

Enum.Parse sẽ xử lý các giá trị nối outputted bởi ToString tốt. Bằng chứng sử dụng cửa sổ ngay lập tức:

? System.Enum.Parse(typeof(System.AttributeTargets), "Class, Enum") 
Class | Enum 

(dòng thứ hai là đầu ra, khác với trình gỡ lỗi/cửa sổ ngay lập tức từ đầu ra Enum.ToString() chung).

21

Nếu bạn thực sự chỉ muốn các dây, không thể có được đơn giản hơn nhiều so với:

string[] flags = role.ToString().Split(',');

Đây là đơn giản hơn so với sử dụng LINQ và vẫn chỉ là một dòng mã. Hoặc nếu bạn muốn có một danh sách thay vì một mảng như trong mẫu trong câu hỏi mà bạn có thể chuyển đổi mảng vào một danh sách:

List<string> flags = new List<string>(role.ToString().Split(','));

Trong trường hợp của tôi, tôi cần một giải pháp chung chung và đến với điều này:

value.ToString().Split(',').Select(flag => (T)Enum.Parse(typeof(T), flag)).ToList();

+0

Câu trả lời hay nhất. Cảm ơn bạn! – Ricsie

Các vấn đề liên quan