Conversão de int para enum em C#: por que isso quebra o código e como corrigir corretamente
\n\nTodo 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.
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\nErro nº 1: Conversão ingênua sem verificação — «E se o número for inválido?»
\n\nA forma mais comum que os iniciantes encontram na internet é a conversão direta:
\n\nenum 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\nO 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.
Como evitar: sempre use o método Enum.IsDefined() antes da conversão.
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\nLembre-se: Enum.IsDefined() é lento em chamadas frequentes, mas para operações pontuais é o guardião ideal.
Erro nº 2: Ignorar enumerações com flags ([Flags])
\n\nAo 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.
[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\nPara flags, é necessário usar outra verificação: todos os bits no número correspondem a valores definidos.
\n\nbool 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\nOu, de forma mais simples, use a verificação embutida Enum.IsDefined() para cada flag individual, se forem poucas.
Erro nº 3: Esquecer o tratamento de números negativos e estouro
\n\nEnum 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.
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
Leia também
Chat-bots em Go: Escrevendo um assistente rápido e confiável do zero
Generics em Rust: para que servem e como usar na prática
Testes em Go: unit, integration, e2e do A ao Z
Como conectar a API do ChatGPT a um projeto Kotlin: guia passo a passo
Como sobrescrever o tipo de propriedade de interface de um arquivo .d.ts no TypeScript: Guia completo