Parse string a enum type

Tengo un tipo de enumeración como este a modo de ejemplo:

public Enum MyEnum { enum1, enum2, enum3 }; 

Leeré una cadena desde el archivo de configuración. Lo que necesito para analizar la cadena al tipo MyEnum o nulo o no definido. No estoy seguro si los siguientes códigos funcionarán (lo siento por no tener acceso a mi VS en este momento):

 // example: ParseEnum("ENUM1", ref eVal); bool ParseEnum(string value1, ref eVal) where T : Enum { bool bRet = false; var x = from x in Enum.GetNames(typeof(T)) where string.Equals(value1, x, StringComparison. OrdinalIgnoreCase) select x; if (x.Count() == 1 ) { eVal = Enum.Parse(typeof(T), x.Item(0)) as T; bRet = true; } return bRet; } 

¿No está seguro si es correcto o hay alguna otra manera simple de analizar una cadena en el valor de MyEnum?

¿Qué tal algo así como:

 public static class EnumUtils { public static Nullable Parse(string input) where T : struct { //since we cant do a generic type constraint if (!typeof(T).IsEnum) { throw new ArgumentException("Generic Type 'T' must be an Enum"); } if (!string.IsNullOrEmpty(input)) { if (Enum.GetNames(typeof(T)).Any( e => e.Trim().ToUpperInvariant() == input.Trim().ToUpperInvariant())) { return (T)Enum.Parse(typeof(T), input, true); } } return null; } } 

Usado como:

 MyEnum? value = EnumUtils.Parse("foo"); 

(Nota: la versión anterior usaba try/catch alrededor de Enum.Parse )

 private enum MyEnum { Enum1 = 1, Enum2 = 2, Enum3 = 3, Enum4 = 4, Enum5 = 5, Enum6 = 6, Enum7 = 7, Enum8 = 8, Enum9 = 9, Enum10 = 10 } private static Object ParseEnum(string s) { try { var o = Enum.Parse(typeof (T), s); return (T)o; } catch(ArgumentException) { return null; } } static void Main(string[] args) { Console.WriteLine(ParseEnum("Enum11")); Console.WriteLine(ParseEnum("Enum1")); Console.WriteLine(ParseEnum("Enum6").GetType()); Console.WriteLine(ParseEnum("Enum10")); } 

SALIDA:

  //This line is empty as Enum11 is not there and function returns a null Enum1 TestApp.Program+MyEnum Enum10 Press any key to continue . . . 

Esta es una vieja pregunta, pero ahora .NET 4.5 tiene Enum.TryParse ().

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

Tengo un método TryParseName en UnconstrainedMelody , una biblioteca para delegates y métodos de utilidad enum que utiliza restricciones “inexpresables” a través de algunos trucos postconstrucción. (El código que usa la biblioteca no necesita un postbuilding, solo para ser claro).

Lo usarías así:

 Foo foo; bool parsed = Enums.TryParseName(name, out foo); 

Actualmente no tengo una versión insensible a mayúsculas y minúsculas, pero podría introducirla fácilmente si quisiera. Tenga en cuenta que esto no intenta analizar los números, por ejemplo “12” como lo hace la versión incorporada, ni intenta analizar las listas de banderas separadas por comas. Puedo agregar la versión de indicadores más adelante, pero no veo mucho sentido en la versión numérica.

Esto se hace sin boxeo y sin verificación de tipo de tiempo de ejecución. Tener la restricción es realmente útil 🙂

Avíseme si encuentra útil un análisis sintáctico de mayúsculas y minúsculas …

Acabo de combinar la syntax desde aquí , con el manejo de excepciones desde aquí , para crear esto:

 public static class Enum { public static T Parse(string value) { //Null check if(value == null) throw new ArgumentNullException("value"); //Empty string check value = value.Trim(); if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value"); //Not enum check Type t = typeof(T); if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "TEnum"); return (T)Enum.Parse(typeof(T), value); } } 

Podría girarlo un poco para devolver nulo en lugar de lanzar excepciones.

Si usa .NET 3.5 (o incluso 2.0, si elimina el método de extensión), he tenido mucha suerte con las técnicas de este artículo:

Enumeraciones y cadenas – ¡Alto a la locura!

EDITAR: el dominio se ha ido y ahora es una granja de enlaces. Saqué el código (ligeramente modificado y agregado con el tiempo) de nuestra base de código en el trabajo, que ahora puedes encontrar aquí:

https://gist.github.com/1305566

Puede usar TryParse si quiere evitar el uso de try / catch.

 MyEnum eVal; if (Enum.TryParse("ENUM2", true, out eVal)){ // now eVal is the enumeration element: enum2 } //unable to parse. You can log the error, exit, redirect, etc... 

Modifiqué la respuesta seleccionada un poco. Espero que te guste.

 public static class EnumUtils { public static Nullable Parse(string input) where T : struct { //since we cant do a generic type constraint if (!typeof(T).IsEnum) { throw new ArgumentException("Generic Type 'T' must be an Enum"); } int intVal; if (!string.IsNullOrEmpty(input) && !int.TryParse(input, out intVal)) { T eVal; if (Enum.TryParse(input, true, out eVal)) { return eVal; } } return null; } } 

Para devolver Enum por cadena, si contiene:

  public static T GetEnum(string s) { Array arr = Enum.GetValues(typeof(T)); foreach (var x in arr) { if (x.ToString().Contains(s)) return (T)x; } return default(T); }