Pourquoi est-il acceptable pour un enum pour avoir deux noms différents avec la même valeur numérique?
Je viens de découvrir un bug subtil où j'ai eu un enum avec deux noms unintentially partage la même valeur numérique (en rouge=10 et crimson=10). Je suis un peu surpris de découvrir que ce n'est pas une erreur de syntaxe.
public enum Colour
{
Red=10,
Blue=11,
Green=12,
Crimson=10
}
//Debug.Write(Colour.Red==Colour.Crimson) outputs True
Est-il vrai monde, la raison pourquoi ce comportement peut être utile ou ne pense que cela doit être une erreur de syntaxe?
- J'ai pensé que j'étais si intelligent pour penser à demander ce plus de trois ans après, il a été demandé à l'origine.
- Consultez le site web MSDN lignes directrices pour l'enum design: msdn.microsoft.com/en-us/library/ms229058.aspx Dans cet esprit, je dirais que même si c'est techniquement possible, ce n'est probablement pas conseillé.
- ensuite, j'allais demander la même chose encore 16 mois après.
- J'ai essayé de créer un
Dictionary<ExternalEnum, TValue>
oùExternalEnum
est externe dans une assemblée, je ne peux pas modifier. Le dictionnaire nécessaires pour avoir une valeur pour chaque valeur d'enum enExternalEnum
, mais deux valeurs dansExternalEnum
ont la même valeur numérique. J'ai ensuite obtenu une ArgumentException parce que (je pense) le dictionnaire est indexée sur la valeur numérique derrière les coulisses - depuis, j'ai dû l'exclure, le double de la valeur à partir du dictionnaire.
Vous devez vous connecter pour publier un commentaire.
One should use it if one needs to use it.
Exemple : je suis en train de travailler sur un programme qui utilise le courant et quelques images précédentes pour le traitement de la vidéo. - Je stocker les images précédentes dans un tableau et j'utiliseenums
pour l'indexation. Dans un mode de fonctionnement, j'ai besoin de0
à l'image précédente et dans un autre mode j'ai besoin de0
à gauche de l'image,1
- droit, etc., et il est possible que je pourrais avoir besoin de 0 à une autre image dans une future mise en œuvre d'un autre mode. Dans ce cas, j'utiliseenums
au lieu demagic numbers
pour l'indexation et je crois que ce sera plus propre comme ça.Méfiez-vous! Si votre
enum
a plusieurs éléments avec la même valeur, vous pouvez obtenir des résultats inattendus lorsque vous utilisezEnum.Parse()
. Faire arbitrairement retourner le premier élément qui a la valeur demandée. Par exemple, si vous avezenum Car { Ford = 1, Chevy = 1, Mazda = 1}
, puis(Car)Enum.Parse(typeof(Car), "1")
sera de retourCar.Ford
. Même si ça peut être utile (je ne sais pas pourquoi il en serait ainsi, dans la plupart des situations, il va probablement être source de confusion (en particulier pour les ingénieurs de maintenir le code) ou facilement négligés lorsque des problèmes surviennent.surround the text
avec backtick (`) ou utiliser le code devis bouton dans la barre de formatage. Je suppose que vos upvote nombre peut encore augmenter si c'est un peu plus facile à lire. Bonne chance.J'ai vu que cette fonctionnalité est parfois utilisé pour une valeur "par défaut":
Mais attention, ce n'est que du sucre pour l'utilisateur de votre enum. Juste parce qu'il est appelé par Défaut cela ne signifie pas que c'est la valeur initiale.
Les Enums sont utilisées comme constans et vous avez certainement peut avoir deux constantes avec la même valeur qui sont utilisés dans les mêmes endroits. Il peut l'être en raison de la 3e partie de l'API, en raison de la compatibilité descendante ot juste parce que des règles d'entreprise.
À partir du langage c# spec:
Plusieurs enum membres peuvent partager la même valeur associée. L'exemple
montre un enum dans laquelle deux enum membres—Bleu et Max ont la même valeur associée.
Dans ce cas vous pouvez le vérifier MyColor == Color.Max qui serait utile, c'est certaines circonstances.
Enum est Énumération des variables constantes, et vous pouvez avoir deux éléments ayant la même valeur,il n'y a aucune raison d'être une erreur de syntaxe que je pense, cependant, cela provoque une erreur de compilation dans le présent code
Ce n'est pas une erreur de syntaxe. Tous un
enum
n'est énumérer une série de constantes dans un typage fort de la mode.Ainsi, si un développeur mistypes (comme dans votre exemple), autant que le CLR est en cause, qui est parfaitement valide. Le CLR suppose que le développeur sait ce qu'il fait, et pourquoi il a choisi de le faire.
Comme dans le monde réel cas, je ne peux pas venir avec tout sur l'éperon-of-the-moment, mais je suis certain qu'il y a sans doute des occasions où il serait utile.
Sûr qu'il y est, mais c'est peut-être pas trop commun. Si il y a une entité/valeur qui est communément connu sous deux noms différents, alors que c'est une bonne raison.
Le scénario que vous avez présenté est peut-être l'un de ces cas. Un encore mieux, directement à partir de la BCL, est le
System.De Windows.Les formulaires.MessageBoxIcon
enum; laStop
,Error
, etHand
les membres ont tous la même description et en effet la même valeur.Asterisk
etInformation
sont également identiques, comme le suggèrent les commentaires:J'espère que ce devrait vous donner une bonne idée de scénarios appropriés (votre propre étant probablement l'un).
C'est la fin. Vous pourriez avoir deux valeurs différentes du point de vue de l'utilisateur d'une API, mais fonctionnellement peuvent être traités de la même valeur.
En utilisant par valeur nommée par opposition à la valeur réelle est la racine. Supposons que vous avez le français, l'anglais, etc. avec la même valeur. C'est la racine de l'enum pour moi.
Il est parfois recommandé (bien que pas recommandé par MS pour le C#! - voir Salaros commentaire) pour y inclure une inférieure et la limite supérieure dans votre enum comme
Aux fins de la validation et de l'itération sur chaque paramètre. Si j'ai le sentiment que .Net peut fournir des installations pour cela 🙂
Ceci est valable et permet de renvoyer la même valeur avec des noms différents.
Attention, cela fonctionne bien en un sens univoque. Vous pouvez obtenir des résultats incohérents si vous êtes à la conversion de int/string enum ou pendant le formatage des chaînes de caractères.
Par exemple:
De sortie:
Cet exemple va montrer pourquoi c'est utile. Lorsque vous travaillez sur la bibliothèque publique, qui est dédié à l'usage du public, le nommant mêmes choses d'une manière différente peut être utile.
Lors de différents mots ont la même signification dans certaines situations, il n'a de sens, de les nommer. Lors de l'analyse, c'est toujours le retour de la bonne valeur dans cette situation.
J'ai vu la même chose dans un .net TWAIN wrapper - il permet à tous les TWAIN codes de message pour être stocké dans une grande enum, mais il ne rendre les choses un peu déroutant au premier abord.
Je pense qu'il y a de nombreuses utilisations pour les ré-utiliser le même numéro. Pour donner un nouvel exemple, disons que vous avez un système de classement qui permettra de s'assurer que les objets d'une classe en particulier (Parent) sont créés avant les autres classes qui en dépendent (les Enfants), vous pouvez avoir des enfants qui sont dans la même "niveau" et il n'est pas question que l'un est créé en premier. Dans l'exemple ci-dessous, Mère devrait être créé en premier, l'Enfant de 1, 2 ou 3 suivant, puis le dernier serait Child4. Si cela était considéré comme une arborescence, tous les éléments avec le même nombre serait " que les frères et sœurs.
Bien que je peux voir votre point de vue, cela pourrait être facile à faire, par erreur. Dans ce cas, il serait pratique si visual studio avait une option pour activer les avertissements qui laisserait compiler mais soulèverait un avertissement si le même numéro a été utilisé deux fois.
J'ai pensé qu'il serait utile pour la cartographie domaine, par exemple (dans LinqPad):
L'objectif est l'utilisation la plus courte des noms, cependant, les résultats de l'analyse ou TryParse ne sont pas compatibles, et ce code sorties: