Conversão de int para enum em C#: 5 erros fatais e como evitá-los

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Conversão de int para enum em C#: por que isso quebra o código e como corrigir corretamente

\n\n

Todo desenvolvedor C#, mesmo com alguns meses de experiência, mais cedo ou mais tarde se depara com a pergunta: «How do I cast int to enum in C#?». Esta consulta no Stack Overflow acumulou centenas de milhares de visualizações — e não é à toa. Parece simples, não? Escreveu (MyEnum)myInt — e pronto. Mas o diabo, como sempre, está nos detalhes. A conversão incorreta de int para enum pode levar a exceções, bugs difíceis de detectar e até mesmo à queda do servidor de produção.

\n\n

Neste artigo, vamos analisar os 5 principais erros ao converter int para enum, mostrar exemplos práticos em C# e fornecer um algoritmo claro para uma conversão segura. Se você programa em C# e usa enumerações, esta informação economizará horas de depuração.

\n\n

Erro nº 1: Conversão ingênua sem verificação — «E se o número for inválido?»

\n\n

A forma mais comum que os iniciantes encontram na internet é a conversão direta:

\n\n
enum Status\n{\n    Active = 1,\n    Inactive = 2,\n    Pending = 3\n}\n\nint input = 5; // O usuário enviou algo errado\nStatus status = (Status)input; // Sem erro, mas status == (Status)5\nConsole.WriteLine(status); // Saída: 5 — valor inválido!\n
\n\n

O código será compilado e executado sem exceção. Mas a variável status agora contém o valor 5, que não existe no enum Status. Em C#, enumerações são, essencialmente, números inteiros com nomes. O compilador não verifica se o valor pertence ao conjunto de constantes. Esta é uma armadilha clássica: a conversão de int para enum funciona tecnicamente, mas logicamente é um bug.

\n\n

Como evitar: sempre use o método Enum.IsDefined() antes da conversão.

\n\n
if (Enum.IsDefined(typeof(Status), input))\n{\n    Status status = (Status)input;\n}\nelse\n{\n    // Tratamento de erro: registro, valor padrão ou exceção\n    Console.WriteLine($"Valor inválido {input} para Status");\n}\n
\n\n

Lembre-se: Enum.IsDefined() é lento em chamadas frequentes, mas para operações pontuais é o guardião ideal.

\n\n

Erro nº 2: Ignorar enumerações com flags ([Flags])

\n\n

Ao trabalhar com enumerações marcadas com o atributo [Flags], a lógica de verificação muda. Enum.IsDefined() retornará false para combinações de flags, mesmo que sejam válidas.

\n\n
[Flags]\nenum Permissions\n{\n    None = 0,\n    Read = 1,\n    Write = 2,\n    Execute = 4\n}\n\nint input = 3; // Read + Write\nif (Enum.IsDefined(typeof(Permissions), input))\n{\n    // Isso não será executado! 3 não é uma constante individual\n}\n
\n\n

Para flags, é necessário usar outra verificação: todos os bits no número correspondem a valores definidos.

\n\n
bool IsValidFlags<T>(int value) where T : Enum\n{\n    int allValues = 0;\n    foreach (var v in Enum.GetValues<T>())\n    {\n        allValues |= Convert.ToInt32(v);\n    }\n    return (value & ~allValues) == 0;\n}\n\nif (IsValidFlags<Permissions>(input))\n{\n    Permissions perms = (Permissions)input; // Seguro\n}\n
\n\n

Ou, de forma mais simples, use a verificação embutida Enum.IsDefined() para cada flag individual, se forem poucas.

\n\n

Erro nº 3: Esquecer o tratamento de números negativos e estouro

\n\n

Enum em C# é baseado por padrão em int, mas pode ser byte, short, long, etc. Se você converter int para enum e o tipo base for byte, corre o risco de obter uma exceção por estouro ou, pior, uma distorção silenciosa do valor.

\n\n
enum SmallEnum : byte\n{\n    A = 0,\n    B = 255\n}\n\nint bigValue = 300;\nSmallEnum se = (SmallEnum)bigValue; // Erro de compilação? Não!\n// Mas o valor será truncado: se == (SmallEnum)44 (300 % 256)\n

                
                

Blogs

Book Recommendations