2011-11-01 6 views
12

Básicamente, una serie de títulos pasará a la instrucción de conmutación y necesito compararlos con los valores de cadena de la enumeración. Pero tengo muy poco o ninguna idea de cómo hacer esto correctamente.Cómo asignar valores de cadena a enumeraciones y usar ese valor en un conmutador

Además, no sé si este es el mejor enfoque así que si alguien tiene alguna idea?

Por ejemplo:

enum 
{ 
    doctor = "doctor", 
    mr = "mr", 
    mrs = "mrs" 
} 

y luego cambiar a través de los valores de cadena que les he asignado.

Respuesta

9

No se puede tener una enum con un tipo de subyacente de string. The underlying type can be any integral type except char.

Si desea traducir un string a su enum entonces es probable que necesite utilizar los Parse o TryParse métodos.

string incoming = "doctor"; 

// throws an exception if the string can't be parsed as a TestEnum 
TestEnum foo = (TestEnum)Enum.Parse(typeof(TestEnum), incoming, true); 

// try to parse the string as a TestEnum without throwing an exception 
TestEnum bar; 
if (Enum.TryParse(incoming, true, out bar)) 
{ 
    // success 
} 
else 
{ 
    // the string isn't an element of TestEnum 
} 

// ... 

enum TestEnum 
{ 
    Doctor, Mr, Mrs 
} 
0

Lea this tutorial para comprender cómo funcionan las enumeraciones. Hay ejemplos de declaraciones switch también.

+0

Revisé pero no vi nada sobre la asignación de valores de cadena allí. – ediblecode

3

Las enumeraciones no pueden ser de tipo cadena.

Los tipos aprobados para una enumeración son byte, sbyte, short, ushort, int, uint, long o ulong.

http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

+0

No dije que quisiera que fuera de tipo cadena. Dije que quería asignarle un valor de cadena. Lo he visto antes y quería saber cómo implementarlo. – ediblecode

+0

Mis disculpas, entonces, lo leí como lo mismo, ya que los valores subyacentes son el tipo de la enumeración. – Jay

4

Este no es el tipo de cosas que deberían estar codificadas. Debe ser impulsado por datos, posiblemente leído desde un archivo externo o base de datos. Puede almacenarlos en un Dictionary y usar las teclas para manejar su lógica.

+0

Eso creía. Gracias – ediblecode

+0

Las descripciones de las enumeraciones de codificación dura no son más incorrectas que nombrar las clases después de objetos de dominio del mundo real. A veces, un Fish.BabelFish siempre será un "pez Babel". Podría hacerse un caso para obtener los valores de un recurso localizado (para la globalización), pero no tiene que obtener cada pieza de información de una base de datos o archivo externo. –

3

Enum solo puede tener tipos subyacentes integrales (excepto char). Por lo tanto, no puedes hacer lo que quieras, al menos directamente.

Sin embargo se puede traducir la cadena que tiene que el tipo de enumeración:

EnumType eVal = (EnumType)Enum.Parse(typeof(EnumType), strValue); 

switch(eVal) 
{ 
    case EnumType.doctor:/*...*/; break; 
    case EnumType.mr: /*...*/; break; 
} 
1

Por qué no usar simplemente enumeración e interruptores pura?

enum Prefix 
{ 
    doctor, 
    mr, 
    mrs 
} 

continuación, puede utilizar es como

string case = "doctor"; 

switch ((Prefix)Enum.Parse(typeof(Prefix), "doctor")) 
{ 
    case Prefix.doctor: 
     ... 
     break; 
    ... 
    default: 
     break; 
} 
+0

enumeraciones tienen que ser una palabra, por lo que Lance Corporal, por ejemplo, me causaría problemas – ediblecode

+1

puede crear un mapa 'Diccionario mapa', llénelo, luego se le da una cadena" Lanza Corporal "encuentre un valor de enumeración apropiado (como 'Prefijo p = map [" Lance Corporal "];') y haz un cambio en el tipo enum. –

2

Creo que la manera estándar de hacer esto es utilizar una clase estática con propiedades de cadena de sólo lectura que devuelven el valor que desee.

16

Descubrí que la mejor manera de hacerlo es mediante el uso del atributo System.ComponentModel.Description en los valores enum.

Aquí se muestra un ejemplo:

using System.ComponentModel; 

public enum ActionCode 
{ 
    [Description("E")] 
    Edit, 
    [Description("D")] 
    Delete, 
    [Description("R")] 
    Restore 
} 

Entonces, para usarlo, crear un método de extensión en una clase estática, así:

Edición: He reescrito el código original como un método de extensión genérica en una clase que implementa IConvertible (Enum implementa esta interfaz, por lo que funciona de la manera que lo necesitamos). Aquí es un método genérico que funciona en todos enumeraciones:

public static string GetDescription<T>(this T e) where T : IConvertible 
{ 
    if (e is Enum) 
    { 
     Type type = e.GetType(); 
     Array values = System.Enum.GetValues(type); 

     foreach (int val in values) 
     { 
      if (val == e.ToInt32(CultureInfo.InvariantCulture)) 
      { 
       var memInfo = type.GetMember(type.GetEnumName(val)); 
       var descriptionAttribute = memInfo[0] 
        .GetCustomAttributes(typeof(DescriptionAttribute), false) 
        .FirstOrDefault() as DescriptionAttribute; 

       if (descriptionAttribute != null) 
       { 
        return descriptionAttribute.Description; 
       } 
      } 
     } 
    } 

    return null; // could also return string.Empty 
} 

lo tanto, para obtener la cadena asociada con nuestra enumeración anterior, se podría utilizar el siguiente código:

using Your.Extension.Method.Namespace; 

... 

ActionCode action = ActionCode.Edit; 
string actionDescription = action.GetDescription(); 

// value of actionDescription will be "E" 

aquí es otra enumeración de muestra:

public enum TestEnum 
{ 
    [Description("This is test 1")] 
    Test1, 
    [Description("This is test 2")] 
    Test2, 
    [Description("This is test 3")] 
    Test3 

} 

Este es el código para ver la descripción:

TestEnum test = TestEnum.Test2; 
var testDescription = test.GetDescription(); 

Los resultados serán:

"This is test 2" 

quería seguir adelante y publicar el método genérico, ya que es mucho más útil. Le impide tener que escribir una extensión personalizada para todas sus enums.

+0

genial con los detalles votados – MonsterMMORPG

1

Quería agregar otra respuesta para cualquier persona que use C# 6 o superior.

Si sólo estás interesado en obtener el nombre del valor de enumeración, se puede usar el método nuevo nombredel() introducido en C# 6.

string enumName = nameof(MyEnum.EnumVal1); // enumName will equal "EnumVal1" 

Si bien esto puede parecer demasiado difícil a primera vista (¿por qué no solo establece el valor de la cadena en "EnumVal1" para comenzar?), le dará una verificación en tiempo de compilación para asegurarse de que el valor sea válido. Entonces, si alguna vez cambia el nombre del valor enum y se olvida de decirle a su IDE que busque y reemplace todas las referencias, no compilará hasta que lo solucione.

Cuestiones relacionadas