153 votes

Un Enum doit-il commencer par un 0 ou un 1 ?

Imaginons que j'ai défini l'Enum suivante :

public enum Status : byte
{
    Inactive = 1,
    Active = 2,
}

Quelle est la meilleure pratique pour utiliser les enum ? Doit-on commencer par 1 comme dans l'exemple ci-dessus ou commencer par 0 (sans les valeurs explicites) comme ceci :

public enum Status : byte
{
    Inactive,
    Active
}

14 votes

Faut-il vraiment les numéroter explicitement ?

168 votes

Les Enums ont été créés juste pour que ce genre de choses n'ait pas d'importance.

9 votes

@Daniel -- arrgh non ! Il est préférable d'utiliser un enum lorsque vous pensez à un booléen fera l'affaire plutôt que d'utiliser un booléen lorsque vous pensez à une énumération.

185voto

Andrey Taptunov Points 4442

Directives de conception du cadre :

✔️ DOIT fournir une valeur de zéro sur les enums simples.

Envisagez d'appeler cette valeur par exemple "Aucun". Si une telle valeur n'est pas appropriée pour cette énumération particulière, la valeur par défaut la plus courante pour l'énumération devrait se voir attribuer la valeur sous-jacente de zéro.

Directives de conception du framework / Conception des drapeaux enums :

❌ ÉVITER d'utiliser des valeurs d'enum de drapeaux de zéro, sauf si la valeur représente " tous les drapeaux sont effacés " et est nommée de manière appropriée, comme le prescrit la ligne directrice suivante.

✔️ DO nommer la valeur zéro des drapeaux enums Aucun. Pour un enum de drapeaux, la valeur doit toujours signifier "tous les drapeaux sont effacés".

33 votes

Échec précoce : Si 'None' n'est pas approprié mais qu'il n'y a pas de valeur logique par défaut, je mettrais quand même une valeur de zéro (et je l'appellerais 'None' ou 'Invalid') qui n'est pas censée être utilisée, juste pour que si un membre de cette classe de l'énumération n'est pas initialisé correctement, la valeur non initialisée puisse être facilement repérée, et dans le cas de l'énumération 'None', la valeur 'Invalid' sera utilisée. switch il passera à l'instruction default où je lance un InvalidEnumArgumentException . Sinon, un programme peut involontairement continuer à fonctionner avec la valeur zéro d'une énumération, qui peut être valide et passer inaperçue.

1 votes

Allon Il semble préférable de ne donner que les valeurs de l'enum que vous savez valides et de vérifier les valeurs non valides dans le setter et/ou le constructeur. De cette façon, vous savez immédiatement si un code ne fonctionne pas correctement plutôt que de permettre à un objet avec des données invalides d'exister pendant un temps inconnu et de le découvrir plus tard. À moins que "None" ne représente un état valide, vous ne devriez pas l'utiliser.

0 votes

@SoloBold : Cela ressemble à un cas où vous n'oubliez pas d'initialiser un membre de la classe enum dans un constructeur. Aucune quantité de validation ne vous aidera si vous oubliez d'initialiser ou d'oublier de valider. De plus, il existe des classes DTO simples qui n'ont pas de constructeur, mais qui s'appuient sur les éléments suivants initialisateurs d'objets à la place. La recherche d'un tel bug peut être extrêmement pénible. Quoi qu'il en soit, l'ajout d'une valeur d'énumération inutilisée rend l'API affreuse. Je l'éviterais pour les API destinées à la consommation publique.

75voto

pstrjds Points 6353

Eh bien, je pense que je ne suis pas d'accord avec la plupart des réponses qui disent de ne pas les numéroter explicitement. Je les numérote toujours explicitement, mais c'est parce que dans la plupart des cas, je finis par les persister dans un flux de données où ils sont stockés comme une valeur entière. Si vous n'ajoutez pas explicitement les valeurs et qu'ensuite vous ajoutez une nouvelle valeur, vous pouvez rompre la sérialisation et ne pas être en mesure de charger correctement les anciens objets persistants. Si vous avez l'intention d'effectuer un quelconque stockage persistant de ces valeurs, je vous recommande vivement de définir explicitement ces valeurs.

10 votes

+1, d'accord, mais seulement dans le cas où votre code dépend de l'entier pour une raison externe (par exemple, la sérialisation). Partout ailleurs, vous devriez laisser le framework faire son travail. Si vous comptez sur les valeurs entières en interne, alors vous faites probablement quelque chose de mal (voir : laisser le framework faire son travail).

0 votes

Matthew - Je suis tout à fait d'accord. Dans une grande partie du code que j'écris, je suis en train de sérialiser vers un disque ou une base de données, j'ai donc tendance à persister la valeur entière, et je veux donc que les valeurs soient définies explicitement. Si l'énumération ne doit jamais être persistée, alors je laisse le système définir les valeurs. Comme vous l'avez dit, si vous utilisez les valeurs entières pour la comparaison dans le code, vous faites quelque chose de mal.

3 votes

J'aimerais faire persister le texte de l'énumération. Cela rend la base de données beaucoup plus utilisable.

17voto

Joe Points 60749

Une Enum est un type de valeur et sa valeur par défaut (par exemple pour un champ Enum dans une classe) sera 0 si elle n'est pas initialisée explicitement.

Par conséquent, vous souhaitez généralement avoir 0 comme constante définie (par exemple, Inconnu).

Dans votre exemple, si vous voulez Inactive pour être la valeur par défaut, alors elle doit avoir la valeur zéro. Sinon, vous pouvez envisager d'ajouter une constante Unknown .

Certaines personnes ont recommandé de ne pas spécifier explicitement les valeurs de vos constantes. C'est probablement un bon conseil dans la plupart des cas, mais il y a des cas où vous voudrez le faire :

  • Enums de drapeaux

  • Enums dont les valeurs sont utilisées dans l'interopérabilité avec des systèmes externes (par exemple, COM).

0 votes

J'ai constaté que les enums de drapeaux sont beaucoup plus lisibles lorsque vous Ne le fais pas. définir explicitement les valeurs. -- Il est également beaucoup moins risqué de laisser le compilateur faire les calculs binaires pour vous. (i.e. [Flags] enum MyFlags { None = 0, A, B, Both = A | B, /* etc. */ } est beaucoup plus lisible que [Flags] enum MyFlags { None = 0, A = 1, B = 2, Both = 3, /* etc */ } .)

1 votes

@BrainSlugs83 - Je ne vois pas comment cela pourrait être utile dans le cas général - par ex. [Flags] enum MyFlags { None=0, A, B, C } aurait pour conséquence [Flags] enum MyFlags { None=0, A=1, B=2, C=3 } alors que pour un enum Flags, vous voudriez typiquement C=4.

16voto

FishBasketGordo Points 14957

À moins que vous n'ayez une raison spécifique de les modifier, laissez les enums avec leurs valeurs par défaut, qui commencent à zéro.

public enum Status : byte
{
    Inactive,
    Active
}

5voto

w00te Points 11664

Je dirais que la meilleure pratique est de ne pas les numéroter et de les laisser implicites - ce qui commencerait à 0. Comme c'est implicite, c'est la préférence linguistique qui est toujours bonne à suivre :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X