tags:

views:

56

answers:

4

Possible Duplicate:
How to use Enum with aditional options (All, None)

Somewhat subjective.

I have an enum

public enum Faction {
    Aliance,
    Horde
}

as we all know code closely modeling business domain it is applied is "always better". In a given domain there are two factions, and these two factions are enumerated in the set above.

Question: What are the arguments for and against including special members such as: None, and All in the enum above.

Personally I think those two do not belong there, since there is no such faction as All and None. Also using flags-enum is not appropriate.

The workaround is to have another enum, that will model an affiliation with a faction, in that case it is appropriate to have elements such as All and None in there.

Question #2: Should I create FactionAffiliation enum for the sake of righteousness of the model? Or should I spare myself extra typing and view Faction enum as if it is FactionAffiliation?

Edit: Duplicate of http://stackoverflow.com/questions/2228634/how-to-use-enum-with-aditional-options-all-none

+1  A: 

I look at the use from a more practical view, rather than from pure OO design.

Are there places where you will use a Faction/FactionAffliance where All or None would be not allowed; where you absolutely must have exactly one Faction declared?

If so, then you should use the two separate enums.

If not -- if everywhere you use a faction, "All" and "None" are viable options, then use just one, and call it whatever you like.

James Curran
good answer, +1. Couple realistic examples:model.CharacterFaction = (Faction[]) Enum.GetValues(typeof(Faction));character.Faction = DB.GetCharFaction(character => character.Id == cId);
+2  A: 

I would avoid All and None. Given a Person, say: that Person may belong to one Faction. So to answer the question "Which Faction is this Person in?" we could simply (say) read the Person's faction field. But for the special case of All, the Person who belongs to (say) Horde would also belong to All - even though that Person's faction field != ALL. That changes the meaning of IN, in ways that lead to complicated code and risks of subtle bugs.

Carl Manaster
Good answer. How would you rewrite `FindByFaction(Faction.Any)`?
@user93422: Wouldn't that just be a `FindAll()`?
Svish
@user93422: `foreach (Person p: people) if (p.faction != null) set.add(p);` OR `foreach (Faction f: factions) set.addAll(FindByFaction(f));`
Carl Manaster
+3  A: 

All and None mostly make sense when you're dealing with enumerations you intend to use as bitfields (which you should mark [Flags]). In that case, you should give your first flag a value of 1, and your second a value of 2. Then, None can take the default value of 0 and represent the absence of faction affiliation. The All member is optional as it can be formed by applying a bitwise or on your two other flags. Flags enumerations typically have a plural name, like FactionAffiliations.

If you're not dealing with flags, it's usually better not to include a None value. Most of your program shouldn't need this so it's a special case you won't have to test. If you ever need this None value, consider using a nullable version of your enum instead: Faction?. A nullable enum better represents the absence of a value than a None enumerant.

I assumed your code was C#, but most of the advice should hold in other languages.

Trillian
A: 

I would say that your implementation should be improved.
You're using an enum to model a simple boolean state.
Get rid of the enum altogether and replace it with a boolean property: 'IsAlliance' or 'IsHorde', whichever. An enum is a model for multiple possibilities, and you don't have multiple possibilities.

Task
An enumeration greatly improves code readability over using a boolean value. `Faction.Horde` provides much more semantic information than `false`, especially when it's the third+ argument to a method.
Trillian
Yes, but we're not talking about some loose piece of information here; we're talking about state information on some other object. Some particular thing has one of these two state values, 'IsHorde' or 'IsAlliance', the state value is meaningless when unattached from the thing. Hence, a property. The object property 'this.IsHorde = true' is more readable than 'this.Faction == Faction.Horde' simple because it's fewer characters and operations and concepts. The additional complexity is buying nothing. IMO, anyway. 8 )
Task