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.