La conversione enumerazioni leggibile valori
-
08-06-2019 - |
Domanda
Qualcuno sa come trasformare un valore di enumerazione per un leggibili valore?
Per esempio:
ThisIsValueA dovrebbe essere "Questo è Un Valore".
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.