Все это, конечно, хорошо… Но что делать, если необходимо отображать пользователю списки (например, combobox'ы) состоящие из этих самых enum (или сводящиеся к ним)? Естественно, что пользователь не знает английского, да и в любом случае – адекватно воспринимать замену пробела символом подчеркивания он точно не будет :)
Если вспомнить про то, что юникод для дотнета – это «родное», а студия еще и корректно работает с русскими именами функций и переменных, то можно, конечно, называть значения в нашем enum русскими именами. Но! Это ж умучаешься раскладки переключать :)
Поэтому самое простое неправильное решение – это, как правило, использование строкового массива, в котором задаются отображаемые пользователю русские имена.
Можно пойти дальше и использовать вместо массива, например, Dictionary
Кстати, этот способ имеет право на жизнь. Однако – он неудобен. Намного удобнее, когда описания элементов enum хранятся вместе с ними. Даже очень удобно :)
Как этого добиться? (И вот тут все должны громко воскликнуть – «Ну конечно атрибуты!»)
Первое что нам понадобится – это атрибут, через который мы будем задавать описание:
[AttributeUsage(AttributeTargets.Field)]
public class EnumDescriptionAttribute: Attribute
{
public readonly string description;
public EnumDescriptionAttribute(string description)
{
this.description = description;
}
}
public enum etest
{
[EnumNameAttribute("Значение 1")]
value1,
[EnumNameAttribute("Значение 2")]
value2,
…
}
Как видите – здесь все просто :)А теперь самое сложное: получение этих описаний (чтобы отдать их пользователю).
Примечание: и вот тут-то руки и опускаются – сразу после того, как мы слышим жуткое слово reflection :) Но не пугайтесь, все не так страшно ;)
Чтобы получить наш атрибут-описание для известного значения, надо вызвать следующий код:
((EnumDescriptionAttribute)typeof(etest).GetField(p.ToString()).GetCustomAttributes(typeof(EnumDescriptionAttribute), true)[0]).description;
Примечание: стра-а-ашно??? :)
Чтобы получить имена для всех значений enum (например, чтобы сформировать список, из которого будет производиться выбор нужного значения):
public static string[] GetAllEnumDescription()
{
T[] vals=(T[])Enum.GetValues(typeof(T));
string[] names = new string[vals.Length];
for (int i = 0; i < vals.Length; i++)
names[i] = GetEnumDescription(vals[i]);
return names;
}
public static string GetEnumDescription(T p)
{
return ((EnumDescriptionAttribute)typeof(T).GetField(p.ToString()).GetCustomAttributes(typeof(EnumDescriptionAttribute), true)[0]).description;
}
Примечание: я решил, что данный вариант (использующий generics) функции будет полезнее – этот вариант функции можно использовать для любого enum (при условии, что у его элементов есть наш атрибут). Кому не нравится – его легко можно переделать.
Вообщем-то и всё…
P.S.: ой, нет! Чуть не забыл: если в функции GetAllEnumDescription использовать конструкцию yeld return – то она будет еще более удобна :) и один new можно будет убрать…
Комментариев нет:
Отправить комментарий