No .NET Core e .NET> 4, existe um método de análise genérico :
Enum.TryParse("Active", out StatusEnum myStatus);
Isso também inclui as novas out
variáveis embutidas do C # 7 , o que faz a tentativa de análise, a conversão para o tipo de enum explícito e inicializa + preenche a myStatus
variável.
Se você tiver acesso ao C # 7 e ao .NET mais recente, é a melhor maneira.
Resposta original
No .NET, é bastante feio (até 4 ou mais):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
Costumo simplificar isso com:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Então eu posso fazer:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
Uma opção sugerida nos comentários é adicionar uma extensão, que é bastante simples:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
Por fim, convém usar uma enumeração padrão se a sequência não puder ser analisada:
public static T ToEnum<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}
O que faz desta a chamada:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
No entanto, eu seria cuidadoso ao adicionar um método de extensão como este para string
que (sem controle de namespace) apareça em todas as instâncias, string
se eles possuem um enum ou não (isso 1234.ToString().ToEnum(StatusEnum.None)
seria válido, mas sem sentido). Geralmente, é melhor evitar bagunçar as classes principais da Microsoft com métodos extras que só se aplicam em contextos muito específicos, a menos que toda a equipe de desenvolvimento tenha um entendimento muito bom do que essas extensões fazem.
Use
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Isso pode ser simplificado ainda mais com o tipo de parâmetro do C # 7.0 embutido :
fonte
Parse
gera exceções explicativos para o que deu errado com a conversão (valor foinull
, vazio ou não correspondente constante enum), que é muito melhor do queTryParse
's valor de retorno booleano (que suprime o erro de concreto)var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
Observe que o desempenho de
Enum.Parse()
é péssimo, porque é implementado via reflexão. (O mesmo vale paraEnum.ToString
que acontece na outra direção.)Se você precisar converter seqüências de caracteres para Enums em códigos sensíveis ao desempenho, sua melhor aposta é criar um
Dictionary<String,YourEnum>
na inicialização e usá-lo para fazer suas conversões.fonte
Você está procurando Enum.Parse .
fonte
Você pode usar métodos de extensão agora:
E você pode chamá-los pelo código abaixo (aqui,
FilterType
é um tipo de enumeração):fonte
Portanto, se você tivesse um enum chamado mood, ficaria assim:
fonte
CUIDADO:
Enum.(Try)Parse()
aceita vários argumentos separados por vírgula e os combina com 'ou' binário|
. Você não pode desativar isso e, na minha opinião, quase nunca o deseja.Mesmo se
Three
não fosse definido,x
ainda obteria o valor int3
. Pior ainda: Enum.Parse () pode fornecer um valor que nem está definido para a enumeração!Eu não gostaria de experimentar as conseqüências dos usuários, voluntária ou involuntariamente, desencadeando esse comportamento.
Além disso, como mencionado por outros, o desempenho é inferior ao ideal para enums grandes, ou seja, linear no número de valores possíveis.
Sugiro o seguinte:
fonte
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Significa que você pode configurar seus valores de enum como potências de 2 e você tem uma maneira muito fácil de analisar vários sinalizadores booleanos, por exemplo. "UseSSL, NoRetries, Sync". De fato, é para isso que foi projetado.Enum.Parse é seu amigo:
fonte
Você pode estender a resposta aceita com um valor padrão para evitar exceções:
Então você chama assim:
Se o valor padrão não for uma enumeração, o Enum.TryParse falhará e lançará uma exceção capturada.
Depois de anos usando essa função em nosso código em muitos lugares, talvez seja bom adicionar as informações de que essa operação custa desempenho!
fonte
defaultValue
e o tipo de retorno do método são do tipoT
. Se os tipos forem diferentes, você receberá um erro em tempo de compilação: "não é possível converter de 'ConsoleApp1.Size' para 'ConsoleApp1.Color'" ou quaisquer que sejam seus tipos.Não podíamos assumir entradas perfeitamente válidas e acompanhamos essa variação da resposta de @ Keith:
fonte
fonte
Analisa a string no TEnum sem o método try / catch e sem o método TryParse () do .NET 4.5
fonte
Código super simples usando o TryParse:
fonte
Eu gosto da solução do método de extensão ..
Aqui abaixo minha implementação com testes.
fonte
==================== Um programa completo ====================
fonte
Eu usei classe (versão fortemente tipada do Enum com melhorias de análise e desempenho). Encontrei no GitHub e também deve funcionar no .NET 3.5. Ele possui alguma sobrecarga de memória, pois armazena em buffer um dicionário.
O post do blog é Enums - melhor sintaxe, melhor desempenho e TryParse no NET 3.5 .
E código: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
fonte
Para desempenho, isso pode ajudar:
fonte
Descobri que aqui o caso com valores de enumeração com valor de EnumMember não foi considerado. Aqui vamos nos:
E exemplo dessa enumeração:
fonte
Você precisa usar Enum.Parse para obter o valor do objeto de Enum, depois disso, é necessário alterar o valor do objeto para um valor específico de enum. A conversão para o valor de enum pode ser feita usando Convert.ChangeType. Veja o seguinte snippet de código
fonte
Experimente este exemplo:
Nesta amostra, você pode enviar todas as strings e definir seu
Enum
. Se vocêEnum
tinha os dados desejados, retorne-os como seuEnum
tipo.fonte
newModel
em cada linha; portanto, se ele contiver traços, não será substituído. Além disso, você não tem que verificar se a cadeia contém qualquer coisa, você pode simplesmente chamarReplace
de qualquer maneira:var newModel = model.Replace("-", "").Replace(" ", "");
Não tenho certeza quando isso foi adicionado, mas na classe Enum agora existe uma
Parse<TEnum>(stringValue)
Usado dessa maneira com o exemplo em questão:
var MyStatus = Enum.Parse<StatusEnum >("Active")
ou ignorando o revestimento por:
var MyStatus = Enum.Parse<StatusEnum >("active", true)
Aqui estão os métodos descompilados usados:
fonte
fonte
fonte
Se o nome da propriedade for diferente do que você deseja chamá-lo (ou seja, diferenças de idioma), faça o seguinte:
MyType.cs
EnumExtensions.cs
Program.cs
fonte