Eu li algumas postagens de SO e parece que a operação mais básica está faltando.
public enum LoggingLevel
{
Off = 0,
Error = 1,
Warning = 2,
Info = 3,
Debug = 4,
Trace = 5
};
if (s == "LogLevel")
{
_log.LogLevel = (LoggingLevel)Convert.ToInt32("78");
_log.LogLevel = (LoggingLevel)Enum.Parse(typeof(LoggingLevel), "78");
_log.WriteDebug(_log.LogLevel.ToString());
}
Isso não causa exceções, é um prazer armazenar 78
. Existe uma maneira de validar um valor entrando em uma enumeração?
Respostas:
Confira Enum.IsDefined
Uso:
Este é o exemplo dessa página:
O exemplo exibe a seguinte saída:
fonte
LoggingLevel
usada como armazenamento, depois apresente isso como umLoggingLevel
valor enum.IsDefined
não está funcionando para membros enum bitwised.As soluções acima não lidam com
[Flags]
situações.Minha solução abaixo pode ter alguns problemas de desempenho (tenho certeza de que é possível otimizar de várias maneiras), mas essencialmente sempre provará se um valor de enum é válido ou não .
Baseia-se em três suposições:
int
, absolutamente nada mais-
Chamar
ToString()
um enum retorna oint
valor se nenhum enum (sinalizador ou não) for correspondido. Se um valor de enum permitido for correspondido, ele imprimirá o nome da (s) correspondência (s).Assim:
Com essas duas regras em mente, podemos supor que, se o .NET Framework fizer seu trabalho corretamente, qualquer chamada para o
ToString()
método de uma enum válida resultará em algo que tenha um caractere alfabético como seu primeiro caractere:Pode-se chamá-lo de "hack", mas as vantagens são que, dependendo da implementação
Enum
e dos padrões C # da Microsoft , você não depende de seu próprio código ou cheques com potencial de bugs. Em situações em que o desempenho não é excepcionalmente crítico, isso economiza muitasswitch
declarações desagradáveis ou outras verificações!Editar
Agradecemos a @ChaseMedallion por apontar que minha implementação original não suportava valores negativos. Isso foi corrigido e foram fornecidos testes.
E os testes para fazer backup:
fonte
[Flags]
tiverem valores inteiros sensíveis.A resposta canônica seria
Enum.IsDefined
, mas isso é a: um pouco lento se usado em um circuito fechado eb: não é útil para[Flags]
enumerações.Pessoalmente, eu pararia de me preocupar com isso e
switch
, de maneira adequada, lembrando:default:
(ou tenha um vaziodefault:
explicando o porquê)default:
Igual a:
fonte
Usar:
fonte
Use Enum.IsDefined .
fonte
Para lidar com
[Flags]
você, você também pode usar esta solução no C # Cookbook :Primeiro, adicione um novo
ALL
valor à sua enumeração:Em seguida, verifique se o valor está em
ALL
:fonte
Uma maneira de fazer isso seria confiar na conversão de elenco e enum para string. Ao converter int para um tipo de Enum, o int é convertido em um valor de enum correspondente ou o enum resultante apenas contém int como um valor se o valor de enum não estiver definido para o int.
Não testado para casos extremos.
fonte
Como os outros disseram,
Enum.IsDefined
retornafalse
mesmo se você tiver uma combinação válida de sinalizadores de bits para uma enumeração decorada com oFlagsAttribute
.Infelizmente, a única maneira de criar um método retornando true para sinalizadores de bit válidos é um pouco longa:
Convém armazenar em cache os resultados de
GetCustomAttribute
um dicionário:Observe que o código acima usa a nova
Enum
restrição naT
qual está disponível apenas desde o C # 7.3. Você precisa passar umobject value
em versões mais antigas e acessáGetType()
-lo.fonte