Patterns for flag enums #9471
-
Patterns for flag enumsSummaryIntroduce a ExamplesConsider the following enum: [Flags]
public enum MyEnum {
A = 1,
B = 2,
C = 4,
D = 8,
E = 16,
F = 32,
G = 64
} Note This enum is statically used in the examples below. If statementif (e has A and B and not C) { // equivalent to e.HasFlag(A) && e.HasFlag(B) && !e.HasFlag(C)
...
} Switch statementswitch(e) {
case has A:
...
break;
case has B or C:
...
break;
case has D and E:
...
break;
case has F xor G:
...
break;
...
} Switch expressione switch {
has A => ...,
has B or C => ...,
has D and E => ...,
has F xor G => ...,
...
}; Although this is not necessary, the MotivationThis feature could enhance and simplify working with enums marked as a flag enum (using the Currently, the simplest approach with switch statements looks like this: switch (a) {
case var _ when a.HasFlag(A):
...
break;
case var _ when a.HasFlag(B) || a.HasFlag(C):
...
break;
case var _ when a.HasFlag(D) && a.HasFlag(E):
...
break;
case var _ when a.HasFlag(F) ^ a.HasFlag(G):
...
break;
...
} or in the case of switch expressions: a switch {
_ when a.HasFlag(A) => ...,
_ when a.HasFlag(B) || a.HasFlag(C) => ...,
_ when a.HasFlag(D) && a.HasFlag(E) => ...,
_ when a.HasFlag(F) ^ a.HasFlag(G) => ...,
...
}; |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
Flags in switch’s is weird to me because often flags don’t come with the implication of mutual exclusivity but switch cases do. This makes flags in a switch a potential pit of failure because it’s not clear from natural reading of the syntax that only one of the cases execute. One could argue that “everyone knows only one switch case executes” but even then this feature is limited to scenarios where you have only mutually exclusive flag processing, whereas non mutually exclusive flags do exist and are plentiful. |
Beta Was this translation helpful? Give feedback.
-
I think the situation is somewhat improved by extension properties: MyDaysOfWeek days = MyDaysOfWeek.Monday;
if (days is { HasMonday: true, HasTuesday: false, HasWednesday: true })
{
// handling for Monday + Wednesday schedules
}
[Flags]
public enum MyDaysOfWeek
{
Monday = 1 << 0,
Tuesday = 1 << 1,
Wednesday = 1 << 2,
Thursday = 1 << 3,
Friday = 1 << 4,
Saturday = 1 << 5,
Sunday = 1 << 6
}
public static class MyDaysOfWeekExtensions
{
extension(MyDaysOfWeek value)
{
public bool HasMonday => (value & MyDaysOfWeek.Monday) == MyDaysOfWeek.Monday;
public bool HasTuesday => (value & MyDaysOfWeek.Tuesday) == MyDaysOfWeek.Tuesday;
public bool HasWednesday => (value & MyDaysOfWeek.Wednesday) == MyDaysOfWeek.Wednesday;
// ...
}
} |
Beta Was this translation helpful? Give feedback.
I think the situation is somewhat improved by extension properties: