No se puede asignar un valor enum a una cadena para comenzar. Tendría que llamar al ToString()
, que convertiría Country.UnitedKingdom
a "UnitedKingdom".
Dos opciones se sugieren:
- Crear una
Dictionary<Country, string>
- Una sentencia switch
- Decorar cada valor con un atributo, y la carga que con la reflexión
Comentarios acerca de cada una de ellas ...
Sam código PLE para Dictionary<Country,string>
using System;
using System.Collections.Generic;
enum Country
{
UnitedKingdom,
UnitedStates,
France,
Portugal
}
class Test
{
static readonly Dictionary<Country, string> CountryNames =
new Dictionary<Country, string>
{
{ Country.UnitedKingdom, "UK" },
{ Country.UnitedStates, "US" },
};
static string ConvertCountry(Country country)
{
string name;
return (CountryNames.TryGetValue(country, out name))
? name : country.ToString();
}
static void Main()
{
Console.WriteLine(ConvertCountry(Country.UnitedKingdom));
Console.WriteLine(ConvertCountry(Country.UnitedStates));
Console.WriteLine(ConvertCountry(Country.France));
}
}
Es posible que desee poner la lógica de ConvertCountry
en un método de extensión. Por ejemplo:
// Put this in a non-nested static class
public static string ToBriefName(this Country country)
{
string name;
return (CountryNames.TryGetValue(country, out name))
? name : country.ToString();
}
entonces se podría escribir:
string x = Country.UnitedKingdom.ToBriefName();
Como se ha mencionado en los comentarios, el diccionario comparador predeterminado implicará el boxeo, que no es lo ideal. Por una sola vez, viviría con eso hasta que descubriera que era un cuello de botella. Si estuviera haciendo esto para múltiples enumeraciones, escribiría una clase reutilizable.
sentencia switch
Estoy de acuerdo con yshuditelu's answer lo que sugiere el uso de una declaración switch
de relativamente pocos casos. Sin embargo, ya que cada caso va a ser una sola instrucción, yo personalmente cambiar mi estilo de codificación para esta situación, para mantener el código compacto pero legible:
public static string ToBriefName(this Country country)
{
switch (country)
{
case Country.UnitedKingdom: return "UK";
case Country.UnitedStates: return "US";
default: return country.ToString();
}
}
Puede añadir más casos a esto sin que conseguir demasiado grande, y es fácil mirar a los ojos desde el valor enum hasta el valor de retorno.
DescriptionAttribute
El punto Rado made sobre el código de DescriptionAttribute
ser reutilizable es buena, pero en ese caso se lo recomiendo contra el uso de la reflexión cada vez que se necesita para obtener un valor. Probablemente escribiría una clase estática genérica para mantener una tabla de búsqueda (probablemente un Dictionary
, posiblemente con un comparador personalizado como se menciona en los comentarios). Los métodos de extensión no pueden ser definidos en clases genéricas, por lo que probablemente iba a terminar con algo como:
public static class EnumExtensions
{
public static string ToDescription<T>(this T value) where T : struct
{
return DescriptionLookup<T>.GetDescription(value);
}
private static class DescriptionLookup<T> where T : struct
{
static readonly Dictionary<T, string> Descriptions;
static DescriptionLookup()
{
// Initialize Descriptions here, and probably check
// that T is an enum
}
internal static string GetDescription(T value)
{
string description;
return Descriptions.TryGetValue(value, out description)
? description : value.ToString();
}
}
}
posible duplicado de [C# Cadena enumeraciones] (http://stackoverflow.com/questions/424366/c-sharp-string-enums) – nawfal