如何从描述中获取枚举值?

时间:2009-06-23 15:20:01

标签: c# enums

我有一个表示系统中所有材料汇编代码的枚举:

public enum EAssemblyUnit
{
    [Description("UCAL1")]
    eUCAL1,
    [Description("UCAL1-3CP")]
    eUCAL13CP,
    [Description("UCAL40-3CP")]
    eUCAL403CP, // ...
}

在系统另一部分的遗留代码中,我的对象标记了与枚举描述匹配的字符串。鉴于其中一个字符串,获得枚举值的最简洁方法是什么?我想象的是:

public EAssemblyUnit FromDescription(string AU)
{
    EAssemblyUnit eAU = <value we find with description matching AU>
    return eAU;
}

3 个答案:

答案 0 :(得分:8)

你需要遍历枚举的所有静态字段(这就是它们存储在反射中的方式),找到每个静态字段的描述属性......当你发现正确的属性时,获取字段的值

例如:

public static T GetValue<T>(string description)
{
    foreach (var field in typeof(T).GetFields())
    {
        var descriptions = (DescriptionAttribute[]) 
               field.GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (descriptions.Any(x => x.Description == description))
        {
            return (T) field.GetValue(null);
        }
    }
    throw new SomeException("Description not found");
}

(这是通用的,只是为了让它可以重用于不同的枚举。)

显然,如果你经常这样做,你会想要缓存描述,例如:

public static class DescriptionDictionary<T> where T : struct
{
    private static readonly Dictionary<string, T> Map = 
        new Dictionary<string, T>();

    static DescriptionDictionary()
    {
        if (typeof(T).BaseType != typeof(Enum))
        {
            throw new ArgumentException("Must only use with enums");
        }
        // Could do this with a LINQ query, admittedly...
        foreach (var field in typeof(T).GetFields
                 (BindingFlags.Public | BindingFlags.Static))
        {
            T value = (T) field.GetValue(null);
            foreach (var description in (DescriptionAttribute[]) 
               field.GetCustomAttributes(typeof(DescriptionAttribute), false))
            {
                // TODO: Decide what to do if a description comes up
                // more than once
                Map[description.Description] = value;
            }
        }
    }

    public static T GetValue(string description)
    {
        T ret;
        if (Map.TryGetValue(description, out ret))
        {
            return ret;
        }
        throw new WhateverException("Description not found");
    }
}

答案 1 :(得分:0)

public EAssemblyUnit FromDescription(string AU)
{
    EAssemblyUnit eAU = Enum.Parse(typeof(EAssemblyUnit), AU, true);
    return eAU;
}

答案 2 :(得分:0)

您也可以使用Humanizer。要获得描述,您可以使用:

EAssemblyUnit.eUCAL1.Humanize();

并从描述中获取枚举,您可以使用

"UCAL1".DehumanizeTo<EAssemblyUnit>();

免责声明:我是Humanizer的创作者。