【问题标题】:Finding an enum value by its Description Attribute [duplicate]通过其描述属性查找枚举值[重复]
【发布时间】:2010-08-06 09:13:02
【问题描述】:

这可能看起来有点颠倒,但我想做的是通过它的描述属性从枚举中获取一个枚举值。

所以,如果我有一个如下声明的枚举:

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

我希望能够通过提供字符串“Peter Gouge”来取回 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)
        {

        }
    }
}

但是我不知道该怎么做。也不确定这是否是首先要走的路。

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    使用here描述的扩展方法:

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

    如果没有找到匹配的值,它将返回(Testing)0(你可能想在你的枚举中为这个值定义一个None成员)

    【讨论】:

    • 啊,LINQ 又来救场了。我真的很喜欢这个解决方案,谢谢!
    • -1:在此代码中创建的额外对象:1) RuntimeType,2) cast-iterator,3) lambda 对象,4) WhereIterator。使用 Ani 的解决方案创建的额外对象;没有。
    • 是的,你的方法确实使用了反射,看看你链接到什么,所以你确实需要获取 FieldInfo。您对匿名方法(或 lambda 或其他)的非对象性不正确,因为您正在对“descriptionToMatch”进行闭包捕获,该闭包必须私下捕获其状态引用。
    • @Henrik,是的,GetDescription 方法确实使用反射,我忘记了……但无论如何这是您访问该属性的唯一方法。并且闭包确实生成了一个新类型;当我说它是同一个对象中的方法时我错了,我忘记了闭包。困扰我的只是“lambda对象”一词,因为我认为它不准确,尽管我现在理解您的意思了……无论如何,创建新对象有什么问题? Ani 的解决方案并没有完全回答这个问题,它只给出了特定枚举值的值......
    • 不是吹毛求疵,而是指出它是否对任何人有帮助 - 为了让您的v.GetDescription 工作,您应该将Cast&lt;&gt; 输入Enum,而不是Testing,因为这就是@ 987654329@扩展方法接受。
    【解决方案2】:
    return field.GetRawConstantValue();
    

    如果需要,您当然可以将其转换回测试。

    【讨论】:

    • 它看起来很有希望,但它不起作用。我得到一个InvalidOperationException:“由于对象的当前状态,操作无效。”
    • 刚刚看了下Reflector:唯一真正实现这个方法的类是MdFieldInfo。在RtFieldInfo 中,它只是抛出一个 InvalidOperationException。
    • 它工作正常;您必须跳过枚举中的第一个结果。 typeof(Testing).GetFields[1].GetRawConstantValue();或者,您可以按照 Thomas 的建议过滤类型 MdFieldInfo。这可能是一个更好的解决方案。
    • 确实...第一个字段是value__,它实际上不是枚举成员
    • 正确的方法是过滤实际的GetFields调用:typeof(Testing).GetFields(BindingFlags.Public | BindingFlags.Static)
    【解决方案3】:

    好的,在输入所有内容之后,我认为这是一个一开始就做出决定的案例,导致我走错了路。 Enum 似乎是开始的正确方法,但一个简单的 Dictionary&lt;string, int&gt; 就足够了,而且使用起来要容易得多!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多