Analisar string para o tipo enum

Eu tenho um tipo de enum como este como um exemplo:

public Enum MyEnum { enum1, enum2, enum3 }; 

Eu vou ler uma string do arquivo de configuração. O que eu preciso para analisar a cadeia de caracteres para o tipo MyEnum ou nulo o não definido. Não tenho certeza se os códigos a seguir funcionarão (desculpe por não ter access ao meu VS agora):

 // 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; } 

Não tenho certeza se está correto ou se existe outra maneira simples de analisar uma string para o valor MyEnum?

E sobre algo 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: versão antiga usada try/catch torno 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")); } 

SAÍDA:

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

Essa é uma pergunta antiga, mas agora o .NET 4.5 tem Enum.TryParse ().

http://msdn.microsoft.com/pt-br/library/dd991317.aspx

Eu tenho um método TryParseName em UnconstrainedMelody , uma biblioteca para delegate e enum utilitários methods que usa restrições “inexprimíveis” através de alguns truques postbuild. (Código usando a biblioteca não precisa de um postbuild, apenas para ficar claro.)

Você usaria assim:

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

Eu não tenho atualmente uma versão insensível a maiúsculas e minúsculas, mas eu poderia facilmente apresentar um se você quisesse. Observe que isso não tenta analisar números, por exemplo, “12”, como a versão interna, nem tenta analisar listas de sinalizações separadas por vírgulas. Eu posso adicionar a versão de sinalizadores mais tarde, mas não vejo muito sentido na versão numérica.

Isso é feito sem boxe e sem verificação do tipo de tempo de execução. Ter a restrição é realmente útil 🙂

Por favor, deixe-me saber se você acha útil uma análise insensível a maiúsculas e minúsculas …

Acabei de combinar a syntax daqui , com o tratamento de exceções daqui , para criar isto:

 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); } } 

Você poderia girar um pouco para retornar null em vez de lançar exceções.

Se você estiver usando o .NET 3.5 (ou mesmo 2.0, se você cortar o método de extensão), eu tive muita sorte com as técnicas deste artigo:

Enumerações e cordas – pare a loucura!

EDIT: domínio é ido e agora é um farm de link. Eu puxei o código (ligeiramente modificado e adicionado ao longo do tempo) da nossa base de código no trabalho, que você pode agora encontrar aqui:

https://gist.github.com/1305566

Você pode usar o TryParse se quiser evitar o 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... 

Eu modifiquei a resposta selecionada um pouco. Espero que você goste.

 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 retornar Enum por string, se contiver:

  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); }