Valores de enumeração não exclusivos

Eu estou tentando obscurecer as posições do índice em um arquivo edi … Eu tive uma situação em que 2 ou 3 coisas poderiam estar em um índice com base na situação. Seria legal usar um enum para ocultar os “números mágicos” e ficou surpreso ao ver que você poderia atribuir várias enums ao mesmo valor como este:

public enum Color { Red = 1, Blue = 1, Green = 1 } 

e o compilador está feliz com isso. Eu não esperava que isso funcionasse. Eu não preciso voltar para o enum então não estou preocupado em tentar voltar, mas isso cheira mal. Por que o CLR permite vários valores para enums e devo usar uma estrutura para isso? (A struct parecia dever mais pesado do que um enum e isso parece funcionar)

Na verdade, você já está definindo uma estrutura … Nos bastidores, um enum é apenas uma struct (mas que deriva de System.Enum) e os valores do enum são definidos como constantes (você pode verificar isso com o ILDASM).

Sua definição enum se traduz no seguinte código pseudo C #:

 public struct Color : System.Enum { public const int Red = 1; public const int Blue = 1; public const int Green = 1; } 

O código acima não será compilado em C # porque o compilador não permite definir uma estrutura com uma class base explícita, mas é o que ele emite para uma definição enum.

Como não há problema com um tipo que contém várias constantes que possuem o mesmo valor, não há problema com a definição de enum.

Mas como o enum não possui valores exclusivos, você pode ter um problema ao converter esse enum. Por exemplo, as duas linhas de códigos a seguir retornarão o valor de enum Red, porque o primeiro valor é arbitrariamente selecionado.

 Color color1 = (Color)1; Color color2 = (Color)Enum.Parse(typeof(Color), "1"); 

Estritamente falando, o valor enum não é vermelho, é 1, mas quando você imprime o valor, você verá vermelho.

Além disso, o seguinte booleano é verdade o que parece um pouco estranho …

 // true (Red is Green??) bool b = Color.Red == Color.Green; 

Na linha de fundo isso é perfeitamente legal, mas cabe a você usá-lo quando faz sentido …

Aqui está um link direto para a seção do meu tutorial .NET que discute enumerações sob o capô: http://motti.me/c1E

Isso é perfeitamente legal C #. A partir da especificação de linguagem C # versão 4.0, seção 14.3:

Vários membros enum podem compartilhar o mesmo valor associado. O exemplo

 enum Color { Red, Green, Blue, Max = Blue } 

mostra um enum no qual dois membros enum – Blue e Max – têm o mesmo valor associado.

O mesmo valor numérico, mas nome diferente, nada mais é do que um alias. Poderia ser, por exemplo,

 public enum Color { DefaultColor = 1, Red = 1, Blue = 2 } 

Pode fazer sentido em alguns casos, mas não em muitos. Quando você analisar os valores de volta e chamar colorValue.ToString (), obterá o último valor como valor sequenciado de volta (Vermelho, neste caso), mas perderá o conept de colors padrão, já que é a mesma coisa. Pelo menos da maneira como você modelou seus dados. Se você quiser mantê-lo separado, use valores diferentes para coisas diferentes.

Esta seria uma definição perfeitamente aceitável:

 public enum AllTheThings { TheMoney = 1, TheFreeRides = 1, TheLieThatYouDenied = 2, TheCallsYouveBeenMaking = 3, TheTimesYouveBeenFaking = 4 } 

Se você pensar em cada valor de enum como uma constante, isso faz sentido. Não há razão para que você não consiga ter duas constantes com o mesmo valor:

 public enum MyColor { Blue = 2, Yellow = 3, Green = 4 BlueAndYellow = 4, } 

É o mesmo que:

 public enum MyColor { Blue = 2, Yellow = 3, Green = 4, BlueAndYellow = Green, } 

Essencialmente, você só tem a mesma constante com dois nomes diferentes. BlueAndYellow é um apelido para o Green .

Uma coisa a ser observada aqui é que valores não exclusivos resultam em valores ausentes e duplicados no designer do Visual Studio.

 public enum MyColor { Red= 1, Green= 1, Blue= 2 } 

Se você usar este enum em uma propriedade browable você verá Green, Green, Blue no designer ao invés de Red, Green, Blue .