Словарь значений Enum как строки - PullRequest
3 голосов
/ 08 марта 2012

Я пытаюсь создать API, одна функция в этом API принимает Enum в качестве параметра, который затем соответствует используемой строке.

public enum PackageUnitOfMeasurement
{
        LBS,
        KGS,
};

Тривиальный метод для кодирования этого должен будет перечислять каждыйдело в коде.Но так как их 30, поэтому я стараюсь избегать этого и использую Dictionary Data Structure, но я не могу связать точки о том, как мне соотнести значение с enum.

if(unit == PackageUnitOfMeasurement.LBS)
       uom.Code = "02";  //Please note this value has to be string
else if (unit == PackageUnitOfMeasurement.KGS)
       uom.Code = "03";

Ответы [ 5 ]

9 голосов
/ 08 марта 2012

Вот один способ сохранить отображение в словаре и получить значения позже:

var myDict = new Dictionary<PackageUnitOfMeasurement,string>();
myDict.Add(PackageUnitOfMeasurement.LBS, "02");
...

string code = myDict[PackageUnitOfMeasurement.LBS];

Другой вариант - использовать что-то вроде DecriptionAttribute для украшения каждого перечисленияэлемент и используйте отражение, чтобы прочитать их, как описано в Получение атрибутов значения Enum :

public enum PackageUnitOfMeasurement
{
        [Description("02")]
        LBS,
        [Description("03")]
        KGS,
};


var type = typeof(PackageUnitOfMeasurement);
var memInfo = type.GetMember(PackageUnitOfMeasurement.LBS.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
    false);
var description = ((DescriptionAttribute)attributes[0]).Description;

Преимущество второго подхода состоит в том, что вы держите отображение близко к перечислению иесли что-то изменится, вам не нужно искать другое место, которое вам нужно обновить.

4 голосов
/ 08 марта 2012

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

public enum PackageUnitOfMeasurement {
    None = 0,
    LBS = 2,
    KGS = 3,
    TONS = 0x2a
};

Тогда вы можете просто конвертировать единицы с помощью

uom.Code = ((int)unit).ToString("X2");

Примечание:

Фундаментальный вопрос заключается в том, является ли хорошей идеей жесткое кодирование модулей. Обычно такого рода вещи следует помещать в справочную таблицу в БД, что позволяет легко добавлять новые модули в любое время без необходимости изменения программного кода.


UPDATE:

Я добавил пример, содержащий HEX-код. Формат «X2» дает двухзначное шестнадцатеричное значение. Введите все числа больше 9 в шестнадцатеричном формате, например 0xA == 10, 0x10 == 16 в c #.

2 голосов
/ 08 марта 2012

Я бы использовал атрибуты, прикрепленные к enum.Например:

var type = typeof(PackageUnitOfMeasurement);
var memInfo = type.GetMember(PackageUnitOfMeasurement.LBS.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
    false);
var description = ((DescriptionAttribute)attributes[0]).Description;

Это взято из этого вопроса, Получение атрибутов значения Enum .Который конкретно спрашивает о возврате атрибутов Enum.

1 голос
/ 08 марта 2012

Решение Одеда хорошо, но альтернативой, которую я использовал в прошлом, является использование атрибутов, прикрепленных к значениям перечисления, которые содержат соответствующую строку.

Вот что я сделал.

public class DisplayStringAttribute : Attribute
{
    private readonly string value;
    public string Value
    {
        get { return value; }
    }

    public DisplayStringAttribute(string val)
    {
        value = val;
    }
}

Тогда я мог бы определить мое перечисление следующим образом:

public enum MyState 
{ 
    [DisplayString("Ready")]
    Ready, 
    [DisplayString("Not Ready")]
    NotReady, 
    [DisplayString("Error")]
    Error 
};

И для своих целей я создал преобразователь, чтобы я мог связываться с перечислением:

public class EnumDisplayNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Type t = value.GetType();
        if (t.IsEnum)
        {
            FieldInfo fi = t.GetField(value.ToString());
            DisplayStringAttribute[] attrbs = (DisplayStringAttribute[])fi.GetCustomAttributes(typeof(DisplayStringAttribute),
                false);
            return ((attrbs.Length > 0) && (!String.IsNullOrEmpty(attrbs[0].Value))) ? attrbs[0].Value : value.ToString();
        }
        else
        {
            throw new NotImplementedException("Converter is for enum types only");
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

ОдедРешение, вероятно, работает быстрее, но это решение обладает большой гибкостью.Вы можете добавить целую кучу атрибутов, если действительно хотите.Однако, если вы это сделаете, вам, вероятно, будет лучше создать класс, чем использовать enum!

0 голосов
/ 08 марта 2012

Значение по умолчанию PackageUnitOfMeasurement.LBS равно 0 , аналогично PackageUnitOfMeasurement.KBS равно 1 .

Таким образом, коллекция PackageUnitOfMeasurement действительно является коллекцией, которая содержит целочисленные значения (т. Е. int).

Ваш вопрос не совсем понятен ....

Коллекция словаря имеет Key, а Value звучит так, как будто вы хотите использовать PackageUnitOfMeasurement имеет Key, который тривиален как приведение значения к целому числу.

PackageUnitOfMeasurement example = PackageUnitOfMeasurement.LBS
int result = (int)example;
var myDict = new Dictionary<PackageUnitOfMeasurement,string>(); 
myDict.Add(result,"some value here"
...