2011-11-07 16 views
34

Estoy tratando de ocultar las posiciones del índice en un archivo edi ... Tuve una situación en la que 2 o 3 cosas podrían estar en un índice según la situación. Sería interesante de utilizar una enumeración de ocultar los "números mágicos" y se sorprendió al ver que se podía asignar varias enumeraciones al mismo valor como esto:Valores enum no únicos

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

y el compilador es feliz con esto. No esperaba que esto funcionara. No necesito volver a la enumeración, así que no estoy preocupado por intentar volver, pero este huele a funky. ¿Por qué el CLR permite valores múltiples para enumeraciones y debería usar una estructura para esto? (Una estructura parecía más pesada que una enumeración y esto parece funcionar)

+2

Esta es invariablemente mejor respondió con la pregunta opuesta: ¿por qué sería * * No permitir esto? Es útil cuando, por ejemplo, incluye un primer y último miembro enum. –

+1

cómo desea usar "struct para esto"? – wiero

+0

Podría usar una estructura para obtener el "aspecto" enum y no tendría que lanzar. algo así como "public static int Red {get {return 1;}}" – Rikon

Respuesta

58

Actualmente ya estás definiendo una estructura ... Detrás de escena una enumeración es solo una estructura (pero que deriva de System.Enum) y la los valores de la enumeración se definen como constantes (puede verificar esto con ILDASM).

Su definición de enumeración se traduce en lo siguiente seudo código C#:

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

El código anterior no se compilará en C# porque el compilador no permite definir una estructura con una clase base explícita, pero eso es lo Emite para una definición enum.

Como no hay problema con un tipo que contiene varias constantes que tienen el mismo valor, no hay ningún problema con la definición de enum.

Pero como la enumeración no tiene valores únicos, es posible que tenga un problema al convertir a esta enumeración. Por ejemplo, las siguientes dos líneas de códigos devolverán el valor enum Rojo, porque el primer valor se selecciona arbitrariamente.

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

Estrictamente hablando, el valor enum no es Rojo, es 1, pero cuando imprima el valor, verá Rojo.

Además, la siguiente booleana es verdadera la que se ve un poco raro ...

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

En el fondo esto es perfectamente legal, pero le toca a usted para utilizarlo cuando tiene sentido ...

Aquí hay un enlace directo a la sección de mi .NET tutorial que analiza las enumeraciones bajo el capó: http://motti.me/c1E

+0

Ver también: http://stackoverflow.com/questions/1425777/how-to-prevent-duplicate-values-in-enum – LosManos

+16

Algunos de nosotros somos daltónico rojo-verde, por lo que la última línea de código tiene perfecto sentido ;-) – theMayer

7

el mismo valor numérico, pero diferente nombre no es otra cosa que un alias. Podría ser, p.

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

Puede tener sentido en algunos casos pero no en muchos. Cuando vuelva a analizar los valores y llame a colorValue.ToString() obtendrá el último valor como valor de la cadena de nuevo (Rojo en este caso), pero perderá el cono de colores predeterminados, ya que es la misma cosa. Al menos en la forma en que modeló sus datos. Si desea mantenerlo separado, use diferentes valores para diferentes cosas.

+1

Este es un buen ejemplo de "por qué": porque desea enumerar los valores, pero también el nombre predeterminado (o un mínimo/máximo). –

11

Eso es perfectamente legal C#. Desde C# Language specification versión 4.0, sección 14.3:

Los miembros de enum múltiples pueden compartir el mismo valor asociado.El ejemplo

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

muestra una enumeración en el que dos miembros-Azul ENUM y Max-tienen el mismo valor asociado.

3

Si considera que cada valor enum es una constante, tiene sentido. No hay ninguna razón por qué no debería ser capaz de tener dos constantes con el mismo valor:

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

es lo mismo que:

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

Esencialmente, usted simplemente tienen la misma constante con dos nombres diferentes. BlueAndYellow es un alias para Green.

1

Una cosa a tener en cuenta aquí es que los valores no únicos dan como resultado valores perdidos y duplicados en el diseñador de Visual Studio.

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

si se utiliza esta enumeración en una propiedad browable verá verde, verde, azul en el diseñador en lugar de Rojo, Verde, Azul.

+0

Aunque la información útil, esto no responde a la pregunta, sería más adecuado como un comentario (que pronto tendrá suficientes representantes para publicar) – GHC

4

Esta sería una definición perfectamente aceptable:

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

this.Collection.Select (c => c.Rise()); – Jonathan

+0

¡Oye! Esa es mi línea de código! – Phil

+0

Creo que esto lo convierte en el top 5 en la lista 'fusión de 2 disciplinas separadas' – radsdau