Frage

Weiß jemand, wie man einen Enum-Wert in einen für Menschen lesbaren Wert umwandelt?

Zum Beispiel:

ThisIsValueA sollte „Dies ist Wert A“ lauten.

War es hilfreich?

Lösung

Konvertieren Sie dies aus einem VB-Codeausschnitt, den ein gewisser Ian Horwill bei a hinterlassen hat Blogbeitrag vor langer Zeit...Ich habe dies seitdem erfolgreich in der Produktion eingesetzt.

    /// <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}");
    }

(erfordert 'using System.Text.RegularExpressions;')

Daher:

Console.WriteLine(Wordify(ThisIsValueA.ToString()));

Würde zurückkehren,

"This Is Value A".

Dies ist viel einfacher und weniger redundant als die Bereitstellung von Beschreibungsattributen.

Attribute sind hier nur dann nützlich, wenn Sie eine Indirektionsebene bereitstellen müssen (was in der Frage nicht gefordert wurde).

Andere Tipps

Der .ToString auf Enums ist in C# relativ langsam, vergleichbar mit GetType().Name (unter der Decke könnte es sogar verwendet werden).

Wenn Ihre Lösung sehr schnell oder hocheffizient sein muss, ist es möglicherweise am besten, Ihre Konvertierungen in einem statischen Wörterbuch zwischenzuspeichern und sie von dort aus nachzuschlagen.


Eine kleine Anpassung des Codes von @Leon, um die Vorteile von C#3 zu nutzen.Dies ist als Erweiterung von Aufzählungen durchaus sinnvoll. Sie können dies auf einen bestimmten Typ beschränken, wenn Sie nicht alle überladen möchten.

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();

Die meisten Beispiele hierfür, die ich gesehen habe, beinhalten das Markieren Ihrer Enum-Werte mit [Beschreibung]-Attributen und die Verwendung von Reflektion, um die „Konvertierung“ zwischen dem Wert und der Beschreibung durchzuführen.Hier ist ein alter Blogbeitrag dazu:

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

Sie können von der „Attribute“-Klasse von System.Reflection erben, um Ihre eigene „Description“-Klasse zu erstellen.So (von Hier):

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));
        }
    }
}

Sie können sich auch diesen Artikel ansehen: http://www.codeproject.com/KB/cs/enumdatabinding.aspx

Es geht speziell um die Datenbindung, zeigt aber, wie ein Attribut zum Dekorieren der Enum-Werte verwendet wird, und stellt eine „GetDescription“-Methode zum Abrufen des Texts des Attributs bereit.Das Problem bei der Verwendung des integrierten Beschreibungsattributs besteht darin, dass es andere Verwendungen/Benutzer dieses Attributs gibt, sodass die Möglichkeit besteht, dass die Beschreibung an einer Stelle erscheint, an der Sie sie nicht haben möchten.Das benutzerdefinierte Attribut löst dieses Problem.

Ich fand es am besten, Ihre Enumerationswerte mit einer Unterbewertung zu definieren, sodass ThisIsValueA This_Is_Value_A wäre. Dann können Sie einfach enumValue.toString().Replace("_", ") ausführen, wobei enumValue Ihre Variable ist.

Eine Alternative zum Hinzufügen Description Attribute für jede Aufzählung dienen dazu, eine Erweiterungsmethode zu erstellen.Um Adams „Coolness“-Enumeration wiederzuverwenden:

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));
        }
    }
}

Obwohl dies bedeutet, dass die Beschreibungen weiter von den tatsächlichen Werten entfernt sind, können Sie mithilfe der Lokalisierung unterschiedliche Zeichenfolgen für jede Sprache ausgeben, z. B. in my VeryCool Beispiel.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top