I will share an interesting use I've stumbled across in the past. This example is shamelessly copied from a supplemental answer to the question, "What does the [Flags] Enum Attribute mean in C#?"
[Flags]
public enum MyEnum
{
None = 0,
First = 1 << 0,
Second = 1 << 1,
Third = 1 << 2,
Fourth = 1 << 3
}
This can be easier to expand upon than writing literal 1, 2, 4, 8, ...
values, especially once you get past 17 flags.
The tradeoff is, if you need more than 31 flags (1 << 30
), you also need to be careful to specify your enum as something with a higher upper bound than a signed integer (by declaring it as public enum MyEnum : ulong
, for example, which will give you up to 64 flags). This is because...
1 << 29 == 536870912
1 << 30 == 1073741824
1 << 31 == -2147483648
1 << 32 == 1
1 << 33 == 2
By contrast, if you set an enum value directly to 2147483648, the compiler will throw an error.
As pointed out by ClickRick, even if your enum derives from ulong, your bit shift operation has to be performed against a ulong or your enum values will still be broken.
[Flags]
public enum MyEnum : ulong
{
None = 0,
First = 1 << 0,
Second = 1 << 1,
Third = 1 << 2,
Fourth = 1 << 3,
// Compiler error:
// Constant value '-2147483648' cannot be converted to a 'ulong'
// (Note this wouldn't be thrown if MyEnum derived from long)
ThirtySecond = 1 << 31,
// so what you would have to do instead is...
ThirtySecond = 1UL << 31,
ThirtyThird = 1UL << 32,
ThirtyFourth = 1UL << 33
}