У меня есть перечисление как это:
public enum ObectTypes
{
TypeOne,
TypeTwo,
TypeThree,
...
TypeTwenty
}
затем я должен преобразовать это перечисление для строкового представления. Теперь я делаю этот тот путь:
public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
string result = string.Empty;
switch (typeObj)
{
case ObjectTypes.TypeOne: result = "This is type T123"; break;
case ObjectTypes.TypeTwo: result = "Oh man! This is type T234"; break;
...
case ObjectTypes.TypeTwenty: result = "This is type last"; break;
}
return result;
}
Я совершенно уверен, что существует лучший путь, действительно делают это, я ищу некоторое хорошее решение для практики.
Править: В строке результата нет никакого шаблона.
Заранее спасибо.
Я использую атрибут [Description]
из System.ComponentModel
Пример:
public enum RoleType
{
[Description("Allows access to public information")] Guest = 0,
[Description("Allows access to the blog")] BlogReader = 4,
}
Затем для чтения из это я делаю
public static string ReadDescription<T>(T enumMember)
{
var type = typeof (T);
var fi = type.GetField(enumMember.ToString());
var attributes = (DescriptionAttribute[])
fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
return attributes.Length > 0 ?
attributes[0].Description :
enumMember.ToString();
}
Затем используйте
ReadDescription (RoleType.Guest);
Примечание: это решение предполагает приложение с одной культурой, поскольку ничего специально не спрашивалось о нескольких культурах. Если вы находитесь в ситуации, когда вам необходимо обрабатывать несколько культур, я бы использовал DescriptionAttribute
или аналогичный для хранения ключа к файлу ресурсов с учетом культуры. Хотя вы можете сохранить член перечисления непосредственно в файле .resx, что создаст максимально возможную связь. Я не вижу причин, по которым вы хотели бы связать внутреннюю работу вашего приложения (имена членов перечисления) с ключевыми значениями, которые существуют для целей интернационализации.
Я не могу в это поверить... Почему никто не предложил файл Resource?
Сопоставление значений enum со строками в скомпилированном коде хорошо и хорошо как быстрый взлом, но в долгосрочной перспективе это плохая практика и затрудняет рефакторинг кода. Что делать, если добавить (или вычесть) значение из enum? Если вы используете строки из файла ресурсов, все, что вам нужно сделать, это добавить (или удалить) одну запись.
Используйте предложенный способ ресурсов:
string GetName(Enum e) {
return Properties.Resources.ResourcesManager.GetString("_enum_"+e.GetType().ToString().Replace('.','_'));
}
Обработка ошибок - это немного больше ..
Я думаю, что самый простой способ - создать функцию, которая сопоставляет значение перечисления и предпочтительное короткое имя, а затем создать другую функцию, которая генерирует полное сообщение.
internal static string MapToName(ObjectTypes value) {
switch (value) {
case ObjectTypes.TypeOne: return "T123";
case ObjectTypes.TypeTwo: return "T234";
...
}
}
public string ConvertToCustomTypeName(ObjectTypes value) {
return String.Format("This is type {0}", MapToName(value));
}
Если вам нужна настраиваемая строка, лучшим вариантом было бы создать Dictionary
и просто выполнить поиск по словарю.
Если вас устраивает функция ToString () по умолчанию, просто используйте typeObj.ToString ();
Для словарного подхода вы можете сделать:
private static Dictionary<ObjectTypes, string> enumLookup;
static MyClass()
{
enumLookup = new Dictionary<ObjectTypes, string>();
enumLookup.Add(ObjectTypes.TypeOne, "This is type T123");
enumLookup.Add(ObjectTypes.TypeTwo, "This is type T234");
// enumLookup.Add...
}
Ваш метод станет:
public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
// Shouldn't need TryGetValue, unless you're expecting people to mess with your enum values...
return enumLookup[typeObj];
}
Однажды я использовал настраиваемый атрибут для полей перечисления, который принимал строковый параметр, а затем написал функцию для извлечения строки при задании значения перечисления.
Если вы просто хотите использовать имя перечисления (например, TypeOne), вы можете просто вызвать ToString () для самого перечисления
typeObj.ToString()
Если вы хотите настраиваемая строка в зависимости от типа, у вас есть несколько различных вариантов. Имеющийся у вас оператор switch в порядке, но его обслуживание будет запутанным, если у вас будет большое количество перечислений. Или вы можете настроить словарь на основе типа перечисления в качестве ключа и строки в качестве значения.
public enum ObectTypes
{
One,
Two
}
Dictionary<ObectTypes, String> myDic = new Dictionary<ObectTypes, string>();
myDic.Add( ObectTypes.One, "Something here for One" );
myDic.Add( ObectTypes.Two, "Something here for Two" );