Domanda

Qualcuno sa come trasformare un valore di enumerazione per un leggibili valore?

Per esempio:

ThisIsValueA dovrebbe essere "Questo è Un Valore".

È stato utile?

Soluzione

La conversione di questo da un frammento di codice vb che un certo Ian Horwill a sinistra blog post tempo fa...da allora ho usato questo in produzione con successo.

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

(richiede, 'utilizzo del Sistema.Di testo.RegularExpressions;')

Quindi:

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

Vorresti tornare,

"This Is Value A".

È molto più semplice, e meno ridondante di fornire una Descrizione degli attributi.

Gli attributi sono utili solo se è necessario per fornire un livello di indirezione (che la questione non è chiedere).

Altri suggerimenti

L' .ToString su Enumerazioni è relativamente lento in C#, comparabili con GetType().Nome (si potrebbe anche usare che sotto le coperte).

Se la soluzione deve essere molto veloce o molto efficiente, si può essere meglio di memorizzazione nella cache per le conversioni in statico dizionario, e guardando da lì.


Un piccolo adattamento di @Leon codice per approfittare di C#3.Questo ha senso, come un'estensione di enumerazioni - si potrebbe limitare questo per il tipo specifico se non voglio ingombrare tutti loro.

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

La maggior parte degli esempi di ciò che ho visto coinvolgere indicare i valori enum con [Descrizione] attributi e l'utilizzo di riflessione per fare la "conversione" tra il valore e la descrizione.Ecco un vecchio post di blog su di esso:

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

Si può ereditare da "Attributo" class di Sistema.Riflessione per creare la tua "Descrizione" classe".Come questo (dal qui):

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

Si può anche dare un'occhiata a questo articolo: http://www.codeproject.com/KB/cs/enumdatabinding.aspx

È specificamente sull'associazione di dati, ma mostra come utilizzare un attributo per decorare i valori enum e fornisce un "GetDescription" metodo per recuperare il testo dell'attributo.Il problema con utilizzando il built-in descrizione attributo è che ci sono altri usi/utenti di tale attributo, quindi c'è una possibilità che la descrizione viene visualizzata in cui non si desidera.L'attributo personalizzato risolve il problema.

Ho trovato che la cosa migliore per definire i tuoi valori enum con un punteggio così ThisIsValueA sarebbe This_Is_Value_A quindi si può solo fare un enumValue.toString().Replace("_"," ") dove enumValue è la tua variabile.

Un'alternativa all'aggiunta di Description gli attributi di ogni enumerazione è quello di creare un metodo di estensione.Per il ri-uso di Adamo "Freddezza" enum:

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

Anche se questo significa che le descrizioni siano più lontano dai valori reali, permette di utilizzare la localizzazione di stampare stringhe diverse per ogni lingua, come nel mio VeryCool esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top