2012-03-08 5 views
3

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

public enum PackageUnitOfMeasurement 
{ 
     LBS, 
     KGS, 
}; 

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

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

'Обратите внимание, что это значение должно быть строкой' - но будут ли все строковые значения строковыми представлениями целых чисел и разными целыми числами? Если это так, вы должны установить целое число, лежащее в основе каждого значения перечисления, а затем написать функцию для правильного преобразования целых чисел в строковое представление, которое вы хотите, например. 2 => «02» и т. Д. – Rawling

+0

+1 Натолкнулся на пример кода для установки значений перечисления в коде, и это, безусловно, более просто, но в моем случае значение также может быть «2a» – PUG

+0

Достаточно справедливо. Bang - простое решение! – Rawling

ответ

9

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

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

string code = myDict[PackageUnitOfMeasurement.LBS]; 

Другой вариант заключается в использовании нечто вроде DecriptionAttribute для украшения каждого элемента перечисления и использования отражения для чтения эти вне, как описано в Getting attributes of Enum's value:

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; 

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

+0

DecriptionAttribute отлично поработал – PUG

1

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

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

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(); 
    } 
} 

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

+0

Это звучит многообещающе, но трудно себе представить, как это будет выглядеть. Можете ли вы опубликовать пример? – Gabe

+0

См. Мой ответ. Это объясняет, что делать. –

+0

@Gabe: Я выкопал свой код и добавил его. Надеюсь, поможет. –

0

Значение по умолчанию PackageUnitOfMeasurement.LBS является также PackageUnitOfMeasurement.KBS является .

Таким образом, коллекция 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" 
2

Я бы использовал атрибуты, прикрепленные к перечислению. Как это:

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; 

Это взято из этого вопроса, Getting attributes of Enum's value. Что конкретно спрашивает о возврате атрибутов Enum.

4

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

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

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

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

ПРИМЕЧАНИЕ:

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


ОБНОВЛЕНИЕ:

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

+0

Это, конечно же, самое простое решение, если строки являются * всегда * целыми значениями. –

+0

@MattBurland - На основании примера нет оснований полагать, что он не всегда будет содержать целые числа. –

+0

@Ramhound: Acutally выглядит как OP теперь прокомментировал, что «2a» является приемлемым значением. (хотя я думаю, вы могли бы использовать hex!) –

Смежные вопросы