2010-08-06 60 views
21

Điều này có vẻ hơi lộn ngược, nhưng những gì tôi muốn có thể làm là nhận được một giá trị enum từ một enum bởi thuộc tính Description của nó.Tìm một giá trị enum bởi thuộc tính mô tả của nó

Vì vậy, nếu tôi có một enum tuyên bố như sau:

enum Testing 
{ 
    [Description("David Gouge")] 
    Dave = 1, 
    [Description("Peter Gouge")] 
    Pete = 2, 
    [Description("Marie Gouge")] 
    Ree = 3 
} 

Tôi muốn để có thể nhận được 2 trở lại bằng cách cung cấp các chuỗi "Peter Gouge".

Như một điểm khởi đầu, tôi có thể lặp qua các lĩnh vực enum và lấy lĩnh vực này với các thuộc tính đúng:

string descriptionToMatch = "Peter Gouge"; 
FieldInfo[] fields = typeof(Testing).GetFields(); 

foreach (FieldInfo field in fields) 
{ 
    if (field.GetCustomAttributes(typeof(DescriptionAttribute), false).Count() > 0) 
    { 
     if (((DescriptionAttribute)field.GetCustomAttributes(typeof(DescriptionAttribute), false)[0]).Description == descriptionToMatch) 
     { 

     } 
    } 
} 

Nhưng sau đó tôi bị mắc kẹt như những gì để làm ở chỗ bên trong nếu. Cũng không chắc chắn nếu đây là cách để đi ở nơi đầu tiên.

Trả lời

27

Sử dụng phương pháp mở rộng được mô tả here:

Testing t = Enum.GetValues(typeof(Testing)) 
       .Cast<Testing>() 
       .FirstOrDefault(v => v.GetDescription() == descriptionToMatch); 

Nếu không có giá trị phù hợp được tìm thấy, nó sẽ trở lại (Testing)0 (bạn có thể muốn xác định một thành viên None trong enum của bạn cho giá trị này)

+1

Ahh, LINQ để giải cứu một lần nữa. Tôi thực sự thích giải pháp này, cảm ơn! – DavidGouge

+0

-1: các đối tượng bổ sung được tạo trong mã này: 1) một RuntimeType, 2) một bộ lặp-lặp, 3) một đối tượng lambda, 4) một bộ điều khiển vị trí. Các đối tượng bổ sung được tạo bằng giải pháp của Ani; không ai. – Henrik

+0

@Henrik, bạn chỉ quên một điều: Giải pháp của Ani giả định bạn đã có FieldInfo, và bạn cần sử dụng sự phản chiếu để lấy nó ... Giải pháp của tôi không sử dụng sự phản chiếu; GetValues ​​được thực hiện nội bộ với mã gốc, vì vậy nó nhanh hơn nhiều so với việc sử dụng sự phản chiếu (ít nhất là 5x nhanh hơn theo các bài kiểm tra của tôi). Chi phí tạo ra một RuntimeType và một WhereIterator là không đáng kể so với sự phản ánh. Đối với "đối tượng lambda", không có thứ như vậy ... nó chỉ là một phương thức ẩn danh được tạo ra trong kiểu hiện hành. –

1

Ok, sau khi nhập tất cả những gì tôi nghĩ đây là trường hợp của quyết định ngay từ đầu, dẫn tôi đi sai đường dẫn. Enum dường như là một cách phù hợp để bắt đầu, nhưng một đơn giản Dictionary<string, int> sẽ đủ và trở thành một địa ngục dễ dàng hơn để làm việc với!

4
return field.GetRawConstantValue(); 

Bạn có thể đưa nó trở lại Kiểm tra nếu cần.

+1

Tuyệt vời, cảm ơn bạn. – DavidGouge

+0

Có vẻ đầy hứa hẹn, nhưng nó không hoạt động. Tôi nhận được một 'InvalidOperationException':" Thao tác không hợp lệ do trạng thái hiện tại của đối tượng. " –

+0

Chỉ cần có một cái nhìn trong Reflector: lớp duy nhất thực sự thực hiện phương thức này là 'MdFieldInfo'. Trong 'RtFieldInfo', nó chỉ ném một InvalidOperationException. –

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