Which is the currently-accepted best practice in terms of C# enum usage, a bitwise [Flags] Enum (compared using | and &) or an IEnumerable of enum values? I'm thinking both from a code-conciseness perspective and from a maintenance perspective.
The only downside to using the Flags approach that I can think of is the inability to enumerate the values without doing the reverse enumeration:
var possibleValues = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>();
var applicableValues = possibleValues.Where(x => (containerClass.EnumProperty & x) == x);
Whereas obviously the IEnumerable is easier to query.
EDIT:
As svick rightly pointed out, the IEnumerable would be perhaps the wrong collection to use, an ISet might be a better example.
-
What would be the purpose of an IEnumerable of enum values? What do you intend to use the Enum for?Oded– Oded2011年12月20日 11:58:41 +00:00Commented Dec 20, 2011 at 11:58
-
To hold a collection of attributes about the container class (the concrete example being attributes about a product, such as "Price Marked" (i.e. has the price printed on the pack)). The options are pre-set, making it a good case for an enum.Ed James– Ed James2011年12月20日 12:01:05 +00:00Commented Dec 20, 2011 at 12:01
1 Answer 1
You can create a method that encapsulates enumerating the flags. This way, using flags is almost as easy as an IEnumerable<T>
.
One reason why I would prefer flags is what those two approaches mean. With flags, you have a set. With IEnumerable<T>
, you have a sequence. That means you have another edge case you have to consider: What if the sequence contains some item more than once?
-
Yes, I'd definitely not repeat the code I posted multiple times (it would work nicely as an extension method). I'm not sure the "more than once" argument is more than an aside, however, as in the situation I described, i.e. dealing with attributes, it would simply not be relevant if the number of matches was 1 or 1000, it would just matter if the attribute was present. Data integrity is another issue ;) Perhaps an ISet<Enum> would suffice to negate your example?Ed James– Ed James2011年12月20日 12:42:36 +00:00Commented Dec 20, 2011 at 12:42
-
@EdWoodcock, except that there is no
ISet<T>
in the .Net library.svick– svick2011年12月20日 13:03:50 +00:00Commented Dec 20, 2011 at 13:03 -
1See: msdn.microsoft.com/en-us/library/dd412081.aspx . It was added in .net 4 I believe.Ed James– Ed James2011年12月20日 13:20:46 +00:00Commented Dec 20, 2011 at 13:20