Кто-нибудь знает, как преобразовать значение enum в удобочитаемое значение человека?
Например:
ThisIsValueA должен быть "Это значение A".
Кто-нибудь знает, как преобразовать значение enum в удобочитаемое значение человека?
Например:
ThisIsValueA должен быть "Это значение A".
Преобразуя это из фрагмента кода vb, что определенный Ян Хорвилл ушел в сообщение в блоге давно... с тех пор я использовал это в производстве успешно.
/// <summary>
/// Add spaces to separate the capitalized words in the string,
/// i.e. insert a space before each uppercase letter that is
/// either preceded by a lowercase letter or followed by a
/// lowercase letter (but not for the first char in string).
/// This keeps groups of uppercase letters - e.g. acronyms - together.
/// </summary>
/// <param name="pascalCaseString">A string in PascalCase</param>
/// <returns></returns>
public static string Wordify(string pascalCaseString)
{
Regex r = new Regex("(?<=[a-z])(?<x>[A-Z])|(?<=.)(?<x>[A-Z])(?=[a-z])");
return r.Replace(pascalCaseString, " ${x}");
}
(требуется, используя System.Text.RegularExpressions; ')
Таким образом:
Console.WriteLine(Wordify(ThisIsValueA.ToString()));
Вернется,
"This Is Value A".
Это намного проще и менее избыточно, чем предоставление атрибутов описания.
Атрибуты полезны здесь, только если вам нужно предоставить слой косвенности (который не задал вопрос).
.ToString on Enums относительно медленный в С#, сопоставимый с GetType(). Имя (возможно, даже использовать это под обложками).
Если ваше решение должно быть очень быстрым или эффективным, вы можете лучше всего кэшировать свои конверсии в статическом словаре и искать их там.
Небольшая адаптация кода @Leon для использования С# 3. Это имеет смысл как расширение перечислений - вы можете ограничить это конкретным типом, если вы не хотите загромождать их всех.
public static string Wordify(this Enum input)
{
Regex r = new Regex("(?<=[a-z])(?<x>[A-Z])|(?<=.)(?<x>[A-Z])(?=[a-z])");
return r.Replace( input.ToString() , " ${x}");
}
//then your calling syntax is down to:
MyEnum.ThisIsA.Wordify();
Большинство примеров этого, которые я видел, включают маркировку ваших значений enum с атрибутами [Description] и использование отражения для "преобразования" между значением и описанием. Вот старое сообщение в блоге об этом:
http://geekswithblogs.net/rakker/archive/2006/05/19/78952.aspx
Вы можете наследовать от класса "Атрибут" System.Reflection, чтобы создать свой собственный класс "Описание". Как это (из здесь):
using System;
using System.Reflection;
namespace FunWithEnum
{
enum Coolness : byte
{
[Description("Not so cool")]
NotSoCool = 5,
Cool, // since description same as ToString no attr are used
[Description("Very cool")]
VeryCool = NotSoCool + 7,
[Description("Super cool")]
SuperCool
}
class Description : Attribute
{
public string Text;
public Description(string text)
{
Text = text;
}
}
class Program
{
static string GetDescription(Enum en)
{
Type type = en.GetType();
MemberInfo[] memInfo = type.GetMember(en.ToString());
if (memInfo != null && memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description), false);
if (attrs != null && attrs.Length > 0)
return ((Description)attrs[0]).Text;
}
return en.ToString();
}
static void Main(string[] args)
{
Coolness coolType1 = Coolness.Cool;
Coolness coolType2 = Coolness.NotSoCool;
Console.WriteLine(GetDescription(coolType1));
Console.WriteLine(GetDescription(coolType2));
}
}
}
Вы также можете взглянуть на эту статью: http://www.codeproject.com/KB/cs/enumdatabinding.aspx
Это особенно касается привязки данных, но показывает, как использовать атрибут для украшения значений перечисления и предоставляет метод GetDescription для извлечения текста атрибута. Проблема с использованием встроенного атрибута описания заключается в том, что есть другие применения/пользователи этого атрибута, поэтому существует вероятность, что описание появится там, где вы этого не хотите. Пользовательский атрибут решает эту проблему.
Я нашел, что лучше всего определить ваши значения enum с помощью оценки, поэтому ThisIsValueA будет This_Is_Value_A, тогда вы можете просто сделать enumValue.toString(). Заменить ( "_", ""), где enumValue - это ваш вариант.