Нельзя присвоить значение enum строке, с которой нужно начинать. Вам нужно будет позвонить ToString()
, что конвертирует Country.UnitedKingdom
в "UnitedKingdom".
Два варианта предлагают себя:
- Создать
Dictionary<Country, string>
- Оператор переключения
- Украсьте каждое значение атрибутом и загрузите его с отражением
Комментарии к каждому из них ...
Пример кода для Dictionary<Country,string>
using System;
using System.Collections.Generic;
enum Country
{
UnitedKingdom,
UnitedStates,
France,
Portugal
}
class Test
{
static readonly Dictionary<Country, string> CountryNames =
new Dictionary<Country, string>
{
{ Country.UnitedKingdom, "UK" },
{ Country.UnitedStates, "US" },
};
static string ConvertCountry(Country country)
{
string name;
return (CountryNames.TryGetValue(country, out name))
? name : country.ToString();
}
static void Main()
{
Console.WriteLine(ConvertCountry(Country.UnitedKingdom));
Console.WriteLine(ConvertCountry(Country.UnitedStates));
Console.WriteLine(ConvertCountry(Country.France));
}
}
Возможно, вы захотите поместить логику ConvertCountry
в метод расширения. Например:
// Put this in a non-nested static class
public static string ToBriefName(this Country country)
{
string name;
return (CountryNames.TryGetValue(country, out name))
? name : country.ToString();
}
Тогда вы могли бы написать:
string x = Country.UnitedKingdom.ToBriefName();
Как уже упоминалось в комментариях, компаратор словаря по умолчанию будет включать в себя бокс, который не идеален. Во-первых, я бы жил с этим, пока не обнаружил, что это узкое место. Если бы я делал это для нескольких перечислений, я написал бы класс многократного использования.
Смена оператора
Я согласен с ответом yshuditelu , предлагающим использовать выражение switch
для относительно небольшого числа случаев. Однако, поскольку каждый случай будет представлять собой одно утверждение, я бы лично изменил свой стиль кодирования для этой ситуации, чтобы код был компактным, но читабельным:
public static string ToBriefName(this Country country)
{
switch (country)
{
case Country.UnitedKingdom: return "UK";
case Country.UnitedStates: return "US";
default: return country.ToString();
}
}
Вы можете добавить к этому больше случаев, не делая их слишком большими, и легко перевести взгляд с перечисляемого значения на возвращаемое.
DescriptionAttribute
Точка Радо сделал о том, что код для DescriptionAttribute
можно многократно использовать, хороший, но в этом случае я бы рекомендовал не использовать отражение каждый раз, когда вам нужно получить значение. Я бы, вероятно, написал общий статический класс для хранения справочной таблицы (вероятно, Dictionary
, возможно, с пользовательским компаратором, как упомянуто в комментариях). Методы расширения не могут быть определены в обобщенных классах, поэтому вы, вероятно, в итоге получите что-то вроде:
public static class EnumExtensions
{
public static string ToDescription<T>(this T value) where T : struct
{
return DescriptionLookup<T>.GetDescription(value);
}
private static class DescriptionLookup<T> where T : struct
{
static readonly Dictionary<T, string> Descriptions;
static DescriptionLookup()
{
// Initialize Descriptions here, and probably check
// that T is an enum
}
internal static string GetDescription(T value)
{
string description;
return Descriptions.TryGetValue(value, out description)
? description : value.ToString();
}
}
}