Valori enumerici non univoci

Sto cercando di oscurare le posizioni dell’indice su un file edi … Ho avuto una situazione in cui 2 o 3 cose potrebbero essere a un indice in base alla situazione. Sarebbe bello usare un enum per hide i “numeri magici” ed è stato sorpreso di vedere che si potevano assegnare più enumerazioni allo stesso valore come questo:

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

e il compilatore è soddisfatto 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 ha un odore funky. Perché il CLR consente più valori per enumerazioni e dovrei usare una struct per questo? (Una struttura sembrava il dovere più pesante di un enum e questo sembra funzionare)

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

La tua definizione enum si traduce nel seguente codice pseudo C #:

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

Il codice sopra non verrà compilato in C # perché il compilatore non consente di definire una struttura con una class base esplicita, ma è ciò 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 potresti 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"); 

A rigor di termini il valore enum non è rosso, è 1, ma quando stampi il valore vedrai il rosso.

Inoltre, il seguente booleano è vero che sembra un po ‘strano …

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

Alla fine questo è perfettamente legale, ma spetta a te usarlo quando ha senso …

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

Questo è perfettamente legale C #. Dalla specifica di linguaggio C # 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 enum in cui due membri enum, Blue e Max, hanno lo stesso valore associato.

Lo stesso valore numerico ma il nome diverso non è altro che un alias. Potrebbe essere eg

 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 colors 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.

Questa sarebbe una definizione perfettamente accettabile:

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

Se si pensa ad ogni valore enum come costante, ha senso. Non c’è 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, } 

Equivale a:

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

Essenzialmente hai solo la stessa costante con due nomi diversi. BlueAndYellow è un alias per Green .

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

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

se usi questa enum in una proprietà acctriggersnte vedrai Verde, Verde, Blu in Designer piuttosto che Rosso, Verde, Blu .