2010-08-06 97 views
21

這看起來有點顛倒,但我想要做的是通過其Description屬性從枚舉中獲取枚舉值。通過其描述屬性查找枚舉值

所以,如果我有一個枚舉聲明如下:

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

我希望能夠通過提供字符串「彼得鑿擊」獲得2回。

作爲一個起點,我可以通過枚舉域迭代,並用正確的屬性搶領域:

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

     } 
    } 
} 

但後來我卡爲在內心的,如果做什麼。也不知道這是否是首先要走的路。

回答

27

使用擴展方法描述here

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

如果沒有找到匹配值,它將返回(Testing)0(你可能想在你的枚舉定義None成員此值)

+1

啊,LINQ再次救援。我非常喜歡這個解決方案,謝謝! – DavidGouge 2010-08-06 09:24:56

+0

-1:在此代碼中創建的額外對象:1)RuntimeType,2)轉換迭代器,3)lambda對象,4)WhereIterator。用Ani的解決方案創建額外的對象;沒有。 – Henrik 2011-03-01 13:45:05

+0

@Henrik,你只是忘了一件事:Ani的解決方案假設你已經有了FieldInfo,並且你需要使用反射來獲得它......我的解決方案不使用反射; GetValues是使用本機代碼在內部實現的,所以它比使用反射快得多(根據我的測試,速度至少快5倍)。與反射相比,創建RuntimeType和WhereIterator的成本可以忽略不計。至於「lambda對象」,沒有這種東西......它只是在當前類型中創建的匿名方法。 – 2011-03-01 14:14:53

1

好吧,打完所有的信息後,我認爲這是一個正確的決定,導致我走錯了路。 Enum似乎是開始的正確方法,但簡單的Dictionary<string, int>就足夠了,並且可以更容易地處理!

4
return field.GetRawConstantValue(); 

如果需要,您當然可以將其重新投入測試。

+1

非常好,謝謝。 – DavidGouge 2010-08-06 09:24:21

+0

它看起來很有希望,但它不起作用。我得到一個'InvalidOperationException':「由於對象的當前狀態,操作無效」。 – 2010-08-06 09:31:25

+0

剛剛看過Reflector:實際實現此方法的唯一類是'MdFieldInfo'。在'RtFieldInfo'中,它只是拋出一個InvalidOperationException異常。 – 2010-08-06 09:37:53