Как я могу получить значение enum из его описания? - PullRequest
4 голосов
/ 23 июня 2009

У меня есть enum, представляющий все коды сборки материалов в системе:

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

В устаревшем коде в другой части системы у меня есть объекты, помеченные строками, которые соответствуют описаниям enum. Учитывая одну из этих строк, каков самый чистый способ получить значение enum? Я представляю что-то вроде:

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

Ответы [ 3 ]

8 голосов
/ 23 июня 2009

Вам нужно будет перебрать все статические поля перечисления (именно так они хранятся в отражении), чтобы найти атрибут Description для каждого из них ... когда вы найдете правильное, получите значение поля .

Например:

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");
    }
}
0 голосов
/ 06 сентября 2013

Вы также можете использовать Humanizer для этого. Чтобы получить описание вы можете использовать:

EAssemblyUnit.eUCAL1.Humanize();

и вернуть перечисление из описания, которое вы можете использовать

"UCAL1".DehumanizeTo<EAssemblyUnit>();

Отказ от ответственности: я создатель Humanizer.

0 голосов
/ 23 июня 2009
public EAssemblyUnit FromDescription(string AU)
{
    EAssemblyUnit eAU = Enum.Parse(typeof(EAssemblyUnit), AU, true);
    return eAU;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...