2010-08-05 8 views
1

Possible en double:
How to use Enum with aditional options (All, None)membres spéciaux à ENUM: Tous et Aucun

Un peu subjectif.

J'ai un ENUM

public enum Faction { 
    Aliance, 
    Horde 
} 

comme nous le savons tous le code de modélisation étroitement domaine commercial, il est appliqué est « toujours mieux ». Dans un domaine donné, il existe deux factions, et ces deux factions sont énumérées dans l'ensemble ci-dessus.

Quels sont les arguments pour et contre l'inclusion de membres spéciaux tels que: None, and All dans le enum ci-dessus.

Personnellement, je pense que ces deux-là n'appartiennent pas, car il n'y a pas de faction comme All and None. L'utilisation de flags-enum n'est pas non plus appropriée.

La solution de contournement est d'avoir une autre énumération, qui va modéliser une affiliation avec une faction, dans ce cas est approprié pour avoir des éléments tels que Tous et Aucun là-dedans.

Question n ° 2: Devrais-je créer une énumération FactionAffiliation pour des raisons de droiture du modèle? Ou devrais-je m'épargner une frappe supplémentaire et voir Faction enum comme s'il est FactionAffiliation?

Edit: en double de How to use Enum with additional options (All, None)

+0

Copie possible de http://stackoverflow.com/questions/2228634/how-to-use-enum-with-aditional-options-all-none. – Trillian

Répondre

1

Je regarde l'utilisation d'une vue plus pratique, plutôt que de la conception OO pur.

Y a-t-il des endroits où vous utiliserez une Faction/FactionAffliance où All ou None ne seront pas autorisés; où vous devez absolument avoir une faction exactement déclarée?

Si oui, alors vous devriez utiliser les deux énumérations séparées.

Si ce n'est pas le cas - si vous utilisez une faction partout, "Toutes" et "Aucune" sont des options viables, utilisez-en une seule et appelez-la comme vous le souhaitez.

+0

bonne réponse, +1. Quelques exemples réalistes: model.CharacterFaction = (Faction []) Enum.GetValues ​​(typeof (Faction)); character.Faction = DB.GetCharFaction (character => character.Id == cId); –

2

Je voudrais éviter tout et rien. Donné une Personne, dites: cette Personne peut appartenir à une Faction. Donc, pour répondre à la question "Dans quelle faction cette personne est-elle?" nous pourrions simplement (disons) lire le champ de la faction de la personne. Mais pour le cas spécial de Tous, la Personne qui appartient à (disons) Horde appartiendrait aussi à Tout - même si le champ de faction de cette Personne! = ALL. Cela change la signification de IN, d'une manière qui conduit à un code compliqué et à des risques de bugs subtils.

+0

Bonne réponse. Comment réécrire 'FindByFaction (Faction.Any)'? –

+0

@ user93422: Cela ne serait-il pas simplement un 'FindAll()'? – Svish

+0

@ user93422: 'foreach (Personne p: personnes) if (p.faction! = Null) set.add (p);' OR 'foreach (Faction f: factions) set.addAll (FindByFaction (f));' –

4

All et None ont surtout du sens lorsque vous traitez des énumérations que vous avez l'intention d'utiliser comme champs de bits (que vous devez marquer [Flags]). Dans ce cas, vous devez attribuer à votre premier indicateur une valeur de 1 et votre deuxième une valeur de 2. Ensuite, None peut prendre la valeur par défaut de 0 et représenter l'absence d'affiliation de faction. Le membre All est facultatif car il peut être formé en appliquant un bit ou sur vos deux autres drapeaux. Les énumérations de drapeaux ont généralement un nom au pluriel, par exemple FactionAffiliations.

Si vous n'utilisez pas de drapeaux, il est généralement préférable de ne pas inclure de valeur None. La plupart de votre programme ne devrait pas avoir besoin de cela, c'est donc un cas spécial que vous n'aurez pas à tester. Si vous avez besoin de cette valeur None, pensez à utiliser une version Null de votre enum à la place: Faction?. Une énumération nullable représente mieux l'absence d'une valeur qu'un énumérateur None. J'ai supposé que votre code était C#, mais la plupart des conseils devraient tenir dans d'autres langues.

0

Je dirais que votre implémentation devrait être améliorée.
Vous utilisez une énumération pour modéliser un état booléen simple. Débarrassez-vous entièrement de l'énumération et remplacez-la par une propriété booléenne: 'IsAlliance' ou 'IsHorde', selon le cas. Une énumération est un modèle pour plusieurs possibilités, et vous n'avez pas plusieurs possibilités.

+0

Une énumération améliore considérablement la lisibilité du code par rapport à l'utilisation d'une valeur booléenne. 'Faction.Horde' fournit beaucoup plus d'informations sémantiques que' false', surtout quand c'est le troisième + argument d'une méthode. – Trillian

+0

Oui, mais nous ne parlons pas ici d'une information approximative; nous parlons d'informations d'état sur un autre objet. Une chose particulière a l'une de ces deux valeurs d'état, 'IsHorde' ou 'IsAlliance', la valeur d'état n'a pas de sens lorsqu'elle est détachée de la chose. Par conséquent, une propriété. La propriété d'objet 'this.IsHorde = true' est plus lisible que 'this.Faction == Faction.Horde' parce que c'est moins de caractères, d'opérations et de concepts. La complexité supplémentaire n'achète rien. OMI, de toute façon. 8) – Task