Reputation: 172230
Let's say I need both an enum both in a flags and in a non-flags variant.
Option 1: I could duplicate everything:
enum Color { Red, Blue, Green }
[Flags]
enum Colors {
None = 0,
Red = 1,
Blue = 2,
Green = 4
}
// use cases
Color currentColor;
Colors supportedColors;
Option 2: I could just use the Flags variant for everything:
Colors currentColor; // ugly, since neither "None" nor "Red | Blue" should be valid
I don't like either of these: In Option 1, Color.Red
, and Colors.Red
are completely unrelated, which might require binding code. In addition, I'd have to keep the two enums synchronized. The drawback of Option 2 is obvious. What I'd actually like is something like
enum Colors = Flag set of Color;
Is there a more elgant solution to this requirement?
Upvotes: 4
Views: 423
Reputation: 1062745
I would simply use the [Flags]
version for everything, and simply ensure in a few places that it is only a single value. You need to do that either way, because even without [Flags]
the following is valid:
var flags = (Color)47; // why not
So you need to check that the Color
is one you were expecting anyway. The [Flags]
will only help serialization/parsing.
Upvotes: 5
Reputation: 620
Recently I had same problem. Solved by option 2, with simple check:
bool IsColorValid(Color color)
{
return (color != 0 && (color & (color - 1)) == 0);
}
Upvotes: 2
Reputation: 1154
Definitely do not make two enums called Color and Colors (option 1). This would make your code very confusing.
Unless I'm missing something, I don't think option 2 is so ugly. In general, it's reasonable to initialize a system parameter to a default value "None" prior to being set at runtime.
Upvotes: 1
Reputation: 39013
The only possible drawback of option 2 is running out of bits. If that's your problem, a flags enum is not suitible for you at all. Instead, make supported colors a HashSet<Color>
Upvotes: 2