2010-08-06 89 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