2010-06-05 17 views
9

¿Hay alguna manera de definir enum en C# como a continuación?valores de cadena enumeración en C#

public enum MyEnum : string 
{ 
    EnGb = "en-gb", 
    FaIr = "fa-ir", 
    ... 
} 

bien, de acuerdo con el enfoque Erick y enlace, estoy usando esto para comprobar el valor válido a partir de la descripción proporcionada:

public static bool IsValidDescription(string description) 
{ 
    var enumType = typeof(Culture); 
    foreach (Enum val in Enum.GetValues(enumType)) 
    { 
     FieldInfo fi = enumType.GetField(val.ToString()); 
     AmbientValueAttribute[] attributes = (AmbientValueAttribute[])fi.GetCustomAttributes(typeof(AmbientValueAttribute), false); 
     AmbientValueAttribute attr = attributes[0]; 
     if (attr.Value.ToString() == description) 
      return true; 
    } 
    return false; 
} 

alguna mejora?

+0

Como puede ver en las respuestas ... el soporte enum en C#, más allá de lo básico, es un poco escaso ... especialmente de su procedencia del mundo C o C++. No dedique demasiado tiempo tratando de lograr que hagan algo que realmente no quieran hacer. Lo hice, por lo que no tiene demasiado :) – Rusty

Respuesta

13

Otra alternativa, no es eficiente pero dando la funcionalidad de enumeración es el uso de un atributo, como esto:

public enum MyEnum 
{ 
    [Description("en-gb")] 
    EnGb, 
    [Description("fa-ir")] 
    FaIr, 
    ... 
} 

Y algo así como un método de extensión, esto es lo que utilizo:

public static string GetDescription<T>(this T enumerationValue) where T : struct 
{ 
    var type = enumerationValue.GetType(); 
    if (!type.IsEnum) throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue"); 
    var str = enumerationValue.ToString(); 
    var memberInfo = type.GetMember(str); 
    if (memberInfo != null && memberInfo.Length > 0) 
    { 
    var attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); 
    if (attrs != null && attrs.Length > 0) 
     return ((DescriptionAttribute) attrs[0]).Description; 
    } 
    return str; 
} 

A continuación, puede llamarlo así:

MyEnum.EnGb.GetDescription() 

Si tiene un atributo de descripción, lo obtiene, si no es así, obtienes la versión .ToString(), p. "EnGb". La razón por la que tengo algo como esto es usar un tipo de enumeración directamente en un objeto Linq-to-SQL, y aún así poder mostrar una bonita descripción en la interfaz de usuario. No estoy seguro de que se ajuste a su caso, pero arrojándolo como una opción.

+0

La misma idea y fui un minuto más rápido, pero tu respuesta es más completa ...;-) – Lucero

+0

@Lucero: tardó un minuto en abrir los archivos del proyecto;) –

+0

@Nick, supongo que sí. Escribir este error habría tomado un minuto más o menos, y como no tenía una muestra a mano, simplemente escribí el "concepto". Tenga en cuenta que, en cuanto a rendimiento, puede que desee agregar un diccionario que correlacione los valores enum con sus cadenas, por lo que no es realmente un problema. – Lucero

1

No. Simplemente puede usar un Dictionary<String, String>. El tipo para una enumeración debe ser un tipo integral distinto de char. Esto es para que puedan ser comparados de manera eficiente.

3

Si todos sus nombres/valores van a ser exactamente así, puede crear una enumeración como de costumbre.

public enum MyEnum 
{ 
    EnGb 
    FaIr 
} 

Y luego cuando se necesita el valor real, obtener el nombre de enumeración como una cadena, lo convierten en minúsculas y añadir un - en el medio.

string value = MyEnum.EnGb.ToString().ToLower().Insert(2, "-"); 
+0

Respuesta de Gud en este escenario en particular. – shashwat

7

En cuanto a la respuesta de Mateo, sugiero que uses Dictionary<MyEnum, String>. Yo lo uso como una propiedad estática:

class MyClass 
{ 
    private static readonly IDictionary<MyEnum, String> dic = new Dictionary<MyEnum, String> 
    { 
     { MyEnum.EnGb, "en-gb" }, 
     { MyEnum.RuRu, "ru-ru" }, 
     ... 
    }; 

    public static IDictionary<MyEnum, String> Dic { get { return dic; } } 
} 
+1

Esto es útil si los valores originales ('EnGb', etc.) se pasarán alrededor de la aplicación. Sin embargo, debes tener cuidado al hacer público el getter del diccionario. Aunque tiene una referencia 'readonly', el diccionario en sí mismo es mutable. –

+1

@Matthew: ¡Gracias por tu consejo! Aquí hay algunas soluciones: http://stackoverflow.com/questions/678379/is-there-a-read-only-generic-dictionary-available-in-net. También otro sin/- para hacer que la propiedad sea 'interna' – abatishchev

1

sólo es posible indirectamente mediante el uso de atributos en los valores de enumeración, así:

public enum MyEnum { 
    [DefaultValue("en-gb")] 
    EnGb, 
    [DefaultValue("fa-ir")] 
    FaIr, 
    ... 
} 

continuación, se puede recuperar el valor de la cadena utilizando la reflexión mediante la lectura de la atributos personalizados en los campos estáticos de la enumeración.