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

Кто-нибудь знает, как преобразовать значение перечисления в удобочитаемое значение?

Например:

ThisIsValueA должно быть «Это значение A».

17.08.2008 12:24:21
7 ОТВЕТОВ
РЕШЕНИЕ

Преобразование этого из фрагмента кода 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".

Это намного проще и менее избыточно, чем предоставление атрибутов Description.

Атрибуты здесь полезны только в том случае, если вам нужно обеспечить уровень косвенности (о котором вопрос не задавался).

17
17.08.2008 13:15:46

Большинство примеров этого, которые я видел, включают разметку значений перечисления с атрибутами [Description] и использование отражения для «преобразования» между значением и описанием. Вот старая запись в блоге об этом:

http://geekswithblogs.net/rakker/archive/2006/05/19/78952.aspx

4
17.08.2008 12:28:36

Вы также можете взглянуть на эту статью: http://www.codeproject.com/KB/cs/enumdatabinding.aspx

В частности, речь идет о привязке данных, но показывает, как использовать атрибут для декорирования значений перечисления, и предоставляет метод «GetDescription» для получения текста атрибута. Проблема с использованием встроенного атрибута description заключается в том, что существуют другие пользователи / пользователи этого атрибута, поэтому существует вероятность, что описание появится там, где вы этого не хотите. Пользовательский атрибут решает эту проблему.

2
17.08.2008 13:00:10

Вы можете наследовать от класса «Attribute» System.Reflection, чтобы создать свой собственный класс «Description». Вот так ( отсюда ):

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));
        }
    }
}
4
25.03.2016 09:48:20
Зачем создавать атрибут описания, если он уже доступен в пространстве имен System.ComponentModel
Nitin Chaudhari 27.08.2010 14:30:32

Я нашел, что лучше всего определить ваши значения перечисления с помощью заниженной оценки, так что ThisIsValueA будет This_Is_Value_A, тогда вы можете просто сделать enumValue.toString (). Replace ("_", ""), где enumValue - ваша переменная.

0
17.08.2008 13:57:07

.ToString в Enums относительно медленный в C #, сравнимый с GetType (). Name (он может даже использовать это под прикрытием).

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


Небольшая адаптация кода @ Leon для использования C # 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();
11
17.08.2008 16:11:11

Альтернативой добавлению Descriptionатрибутов к каждому перечислению является создание метода расширения. Чтобы повторно использовать перечисление Адама "Прохлада":

public enum Coolness
{
    NotSoCool,
    Cool,
    VeryCool,
    SuperCool
}

public static class CoolnessExtensions
{
    public static string ToString(this Coolness coolness)
    {
        switch (coolness)
        {
            case Coolness.NotSoCool:
                return "Not so cool";
            case Coolness.Cool:
                return "Cool";
            case Coolness.VeryCool:
                return "Very cool";
            case Coolness.SuperCool:
                return Properties.Settings.Default["SuperCoolDescription"].ToString();
            default:
                throw new ArgumentException("Unknown amount of coolness", nameof(coolness));
        }
    }
}

Хотя это означает, что описания находятся дальше от фактических значений, это позволяет вам использовать локализацию для печати различных строк для каждого языка, как в моем VeryCoolпримере.

0
28.08.2018 23:58:04