Design de enumeração

Observação

Este conteúdo é reimpresso com permissão da Pearson Education, Inc. de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Essa edição foi publicada em 2008 e, desde então, o livro foi totalmente revisado na terceira edição. Algumas das informações nesta página podem estar desatualizadas.

Enumerações são um tipo especial de valor. Há dois tipos de enumerações: enumerações simples e enumerações de sinalizador.

Enumerações simples representam pequenos conjuntos fechados de opções. Um exemplo comum da enumeração simples é um conjunto de cores.

As enumerações de sinalizador foram projetadas para dar suporte a operações bit a bit nos valores de enumeração. Um exemplo comum da enumeração de sinalizadores é uma lista de opções.

✔️ USE uma enumeração para parâmetros, propriedades e valores retornados fortemente tipados que representam conjuntos de valores.

✔️ PREFIRA usar uma enumeração, em vez de constantes estáticas.

❌ NÃO use uma enumeração para conjuntos abertos (como a versão do sistema operacional, nomes de amigos etc.).

❌ NÃO forneça valores de enumeração reservados destinados a uso futuro.

Você sempre pode simplesmente adicionar valores à enumeração em uma fase posterior. Confira Como adicionar valores a enumerações para mais detalhes sobre como adicionar valores a enumerações. Os valores reservados apenas poluem o conjunto de valores reais e tendem a levar a erros do usuário.

❌ EVITE expor publicamente enumerações com apenas um valor.

Uma prática comum para garantir a extensibilidade futura das APIs C é adicionar parâmetros reservados às assinaturas de método. Esses parâmetros reservados podem ser expressos como enumerações com um só valor padrão. Isso não deve ser feito em APIs gerenciadas. A sobrecarga de método permite adicionar parâmetros em versões futuras.

❌ NÃO inclua valores sentinelas em enumerações.

Embora às vezes sejam úteis para desenvolvedores de estrutura, os valores sentinelas são confusos para os usuários da estrutura. Eles são usados para acompanhar o estado da enumeração, em vez de serem um dos valores do conjunto representado pela enumeração.

✔️ FORNEÇA um valor de zero em enumerações simples.

Considere chamar o valor como "Nenhum". Se esse valor não for apropriado para essa enumeração específica, o valor padrão mais comum para a enumeração deverá receber o valor subjacente de zero.

✔️ CONSIDERE usar Int32 (o padrão na maioria das linguagens de programação) como o tipo subjacente de uma enumeração, a menos que qualquer um dos seguintes seja verdadeiro:

  • A enumeração é uma enumeração de sinalizadores e você tem mais de 32 sinalizadores ou espera ter mais no futuro.

  • O tipo subjacente precisa ser diferente de Int32 para facilitar a interoperabilidade com código não gerenciado esperando enumerações de tamanhos diferentes.

  • Um tipo subjacente menor resultaria em uma economia substancial de espaço. Se você espera que a enumeração seja usada principalmente como um argumento para o fluxo de controle, o tamanho fará pouca diferença. A economia de tamanho poderá ser significativa se:

    • Você espera que a enumeração seja usada como um campo em uma estrutura ou classe instanciada com muita frequência.

    • Você espera que os usuários criem grandes matrizes ou coleções das instâncias de enumeração.

    • Você espera que um grande número de instâncias da enumeração seja serializado.

Para uso na memória, lembre-se de que os objetos gerenciados são sempre alinhados por DWORD, portanto, você precisa efetivamente de várias enumerações ou outras estruturas pequenas em uma instância para empacotar uma enumeração menor para fazer a diferença, pois o tamanho total da instância sempre será arredondado para um DWORD.

✔️ NOMEIE enumerações de sinalizador com substantivos plurais ou frases substantivas e enumerações simples com substantivos singulares ou frases substantivas.

❌ NÃO se estenda System.Enum diretamente.

System.Enum é um tipo especial usado pelo CLR para criar enumerações definidas pelo usuário. A maioria das linguagens de programação oferece um elemento de programação que dá acesso a essa funcionalidade. Por exemplo, em C#, a palavra-chave enum é usada para definir uma enumeração.

Como projetar enumerações de sinalizador

✔️ APLIQUE System.FlagsAttribute para enumerações de sinalizador. Não aplique esse atributo a enumerações simples.

✔️ USE poderes de dois para os valores de enumeração de sinalizador para que possam ser combinados livremente usando a operação OR bit a bit.

✔️ CONSIDERE fornecer valores de enumeração especiais para combinações de sinalizadores comumente usadas.

As operações bit a bit são um conceito avançado e não devem ser necessárias para tarefas simples. ReadWrite é um exemplo desse valor especial.

❌ EVITE criar enumerações de sinalizador em que determinadas combinações de valores são inválidas.

❌ EVITE usar valores de enumeração de sinalizador de zero, a menos que o valor represente "todos os sinalizadores são limpos" e seja nomeado adequadamente, conforme prescrito pela próxima diretriz.

✔️ NOMEIE o valor zero de enumerações de sinalizador None. Para uma enumeração de sinalizador, o valor deve sempre significar "todos os sinalizadores estão limpos".

Como adicionar valor a enumerações

É muito comum descobrir que você precisa adicionar valores a uma enumeração depois de já tê-la enviado. Há um possível problema de compatibilidade do aplicativo quando o valor que acaba de ser adicionado é retornado de uma API, pois aplicativos mal escritos podem não lidar corretamente com o novo valor.

✔️ CONSIDERE adicionar valores a enumerações, apesar de um pequeno risco de compatibilidade.

Se você tiver dados reais sobre incompatibilidades de aplicativo causadas por adições a uma enumeração, considere adicionar uma API que retorne os valores novos e antigos e prefira a API antiga, que deve continuar retornando apenas os valores antigos. Isso garantirá que seus aplicativos continuem sendo compatíveis.

Portions © 2005, 2009 Microsoft Corporation. Todos os direitos reservados.

Reimpresso com permissão da Pearson Education, Inc. das Diretrizes de Design do Framework: convenções, linguagens e padrões para bibliotecas do .NET reutilizável, 2ª edição por Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 por Addison-Wesley Professional como parte da série de desenvolvimento do Microsoft Windows.

Confira também