web-dev-qa-db-fra.com

Valeurs d'énumération non uniques

J'essaie de masquer les positions d'index sur un fichier edi ... J'ai eu une situation où 2 ou 3 choses pourraient être à un index en fonction de la situation. Ce serait cool d'utiliser une énumération pour masquer les "nombres magiques" et j'ai été surpris de voir que vous pouviez attribuer plusieurs énumérations à la même valeur comme ceci:

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

et le compilateur en est satisfait. Je ne m'attendais pas à ce que cela fonctionne. Je n'ai pas besoin de revenir à l'énumération, donc je ne suis pas inquiet d'essayer de revenir en arrière, mais cela sent génial. Pourquoi le CLR autorise-t-il plusieurs valeurs pour les énumérations et dois-je utiliser une structure pour cela? (Une structure semblait plus lourde qu'un enum et cela semble fonctionner)

53
Rikon

En fait, vous définissez déjà une structure ... Dans les coulisses, une énumération n'est qu'une structure (mais qui dérive de System.Enum) et les valeurs de l'énumération sont définies comme des constantes (vous pouvez le vérifier avec ILDASM).

Votre définition d'énumération se traduit par le pseudo code C # suivant:

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

Le code ci-dessus ne se compilera pas en C # car le compilateur ne permet pas de définir une structure avec une classe de base explicite, mais c'est ce qu'il émet pour une définition d'énumération.

Puisqu'il n'y a pas de problème avec un type qui contient plusieurs constantes qui ont la même valeur, il n'y a pas de problème avec la définition d'énumération.

Mais comme l'énumération n'a pas de valeurs uniques, vous pourriez avoir un problème lors de la conversion en cette énumération. Par exemple, les deux lignes de codes suivantes renvoient la valeur d'énumération Rouge, car la première valeur est arbitrairement sélectionnée.

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

À proprement parler, la valeur d'énumération n'est pas rouge, c'est 1, mais lorsque vous imprimez la valeur, vous verrez rouge.

De plus, le booléen suivant est vrai, ce qui semble un peu bizarre ...

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

En fin de compte, c'est parfaitement légal, mais c'est à vous de l'utiliser quand cela a du sens ...

Voici un lien direct vers la section de mon tutoriel .NET qui traite des énumérations sous le capot: http://motti.me/c1E

72
Motti Shaked

C'est parfaitement légal C #. De la spécification du langage C # version 4.0, section 14.3:

Plusieurs membres enum peuvent partager la même valeur associée. L'exemple

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

affiche une énumération dans laquelle deux membres de l'énumération, Blue et Max, ont la même valeur associée.

18
Mark Byers

La même valeur numérique mais un nom différent n'est rien d'autre qu'un alias. Cela pourrait être par exemple.

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

Cela peut avoir un sens dans certains cas, mais pas beaucoup. Lorsque vous analysez les valeurs en arrière et appelez colorValue.ToString (), vous obtiendrez la dernière valeur en tant que valeur stringifiée (rouge dans ce cas), mais vous perdrez le concept de couleurs par défaut car c'est la même chose. Au moins de la manière dont vous avez modélisé vos données. Si vous souhaitez le garder séparé, utilisez des valeurs différentes pour différentes choses.

11
Alois Kraus

Ce serait une définition parfaitement acceptable:

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

Si vous considérez chaque valeur d'énumération comme une constante, cela a du sens. Il n'y a aucune raison pour que vous ne puissiez pas avoir deux constantes avec la même valeur:

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

Est le même que:

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

Essentiellement, vous avez juste la même constante avec deux noms différents. BlueAndYellow est un alias pour Green.

3
Igby Largeman

Une chose à noter ici est que les valeurs non uniques entraînent des valeurs manquantes et dupliquées dans Visual Studio Designer.

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

si vous utilisez cette énumération dans une propriété navigable, vous verrez Vert, Vert, Ble dans le concepteur plutôt que Rouge, Vert, Ble.

1
Zero