2011-11-07 12 views
34

Sto tentando di oscurare le posizioni dell'indice su un file edi ... Avevo una situazione in cui 2 o 3 elementi potrebbero essere in un indice in base alla situazione. Sarebbe bello usare un enum per nascondere i "numeri magici" ed è stato sorpreso di vedere che si potrebbe assegnare più enumerazioni allo stesso valore in questo modo:Valori enumerici non univoci

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

e il compilatore è contento di questo. Non mi aspettavo che funzionasse. Non ho bisogno di tornare all'enumerazione quindi non sono preoccupato di provare a tornare indietro, ma questo odore è funky. Perché il CLR consente più valori per enumerazioni e dovrei usare una struct per questo? (Una struttura sembrava un dovere più pesante di un enume e sembra funzionare)

+2

Questo è invariabilmente meglio risponde con la domanda opposta: perché dovrebbe * non * permettere questo? È utile quando, per esempio, includi un membro First e Last enum. –

+1

come si desidera utilizzare "struct for this"? – wiero

+0

Potrei usare una struttura per ottenere l'aspetto "enum" e non avrei dovuto eseguire il cast. qualcosa come "public static int Red {get {return 1;}}" – Rikon

risposta

58

In realtà stai già definendo una struttura ... Dietro le quinte un enum è solo una struttura (ma che deriva da System.Enum) e il i valori dell'enum sono definiti come costanti (puoi verificarlo con ILDASM).

tua definizione enum si traduce nella seguente pseudo codice C#:

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

Il codice di cui sopra non viene compilato in C#, perché il compilatore non permette la definizione di una struct con una classe base esplicita, ma è quello che emette per una definizione enum.

Poiché non vi sono problemi con un tipo che contiene costanti multiple con lo stesso valore, non vi sono problemi con la definizione enum.

Ma dal momento che l'enumerazione non ha valori univoci, si potrebbe avere un problema durante la conversione in questa enumerazione. Ad esempio la seguente riga di due codici restituirà il valore enum Rosso, poiché il primo valore è selezionato arbitrariamente.

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

In senso stretto il valore di enum non è rosso, è 1, ma quando si stampa il valore vedrete rosso.

Inoltre, il seguente booleano è vero che sembra un po 'strano ...

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

In linea di fondo questo è perfettamente legale, ma è a voi per usarlo quando ha senso ...

Ecco un link diretto alla sezione del mio .NET tutorial che discute le enumerazioni sotto il cofano: http://motti.me/c1E

+0

Vedi anche: http://stackoverflow.com/questions/1425777/how-to-prevent-duplicate-values-in-enum – LosManos

+16

Alcuni di noi sono daltonico rosso-verde, quindi l'ultima riga di codice lì ha perfettamente senso ;-) – theMayer

7

lo stesso valore numerico ma nome diverso non è altro come un alias. Potrebbe essere ad es.

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

Può avere senso in alcuni casi ma non in molti. Quando si analizzano i valori e si chiama colorValue.ToString() si otterrà l'ultimo valore come valore stringificato (in questo caso rosso), ma si perderà il conetto dei colori predefiniti poiché è la stessa cosa. Almeno nel modo in cui hai modellato i tuoi dati. Se vuoi tenerlo separato usa valori diversi per cose diverse.

+1

Questo è un buon esempio "perché": perché vuoi enumerare i valori, ma anche nominare un valore predefinito (o un minimo/massimo). –

11

Questo è perfettamente legale C#. Da C# Language specification versione 4.0, sezione 14.3:

Più membri enum possono condividere lo stesso valore associato.L'esempio

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

mostra un'enumerazione in cui due membri-blu enum e Max-hanno lo stesso valore associato.

3

Se si pensa che ogni valore di enumerazione come costante, ha senso. Non c'è alcun motivo per cui non si dovrebbe essere in grado di avere due costanti con lo stesso valore:

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

è la stessa:

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

In sostanza è sufficiente avere la stessa costante con due nomi diversi. BlueAndYellow è un alias per Green.

1

Una cosa da notare qui è che valori non univoci generano valori mancanti e duplicati nella finestra di progettazione di Visual Studio.

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

se si utilizza questo enum in una proprietà browable vedrete Verde, Verde, Blu in designer piuttosto che Rosso, Verde, Blu.

+0

Anche se le informazioni utili, questo non risponde alla domanda - sarebbe più adatto come commento (che presto avrà abbastanza rep per postare) – GHC

4

Questa sarebbe una definizione perfettamente accettabile:

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

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

+0

Ehi! Questa è la mia linea di codice! – Phil

+0

Credo che questo sia tra i primi 5 nella lista 'fusione di 2 discipline separate' – radsdau

Problemi correlati