47

I wonder a generic way for setting all bits of enum flag to 1. I just would like to have an enum which returns for all comparisons, regardless of other enums.

And this code works;

[Flags]
public enum SomeRightEnum : uint
{
    CanDoNothing = 0,
    CanDoSomething = 1 << 0,
    CanDoSomethingElse = 1 << 1,
    CanDoYetAnotherThing = 1 << 2,
    ...
    DoEverything = 0xFFFFFFFF 
}

But at the code above since it is uint we set the number of "F"s, it wouldn't work if it was int.

So I'll appreciate a generic way of setting all bits of enum flag to 1, regardless of the datatype (int, int64, uint etc)

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
AFgone
  • 1,172
  • 4
  • 16
  • 31

5 Answers5

76

Easiest is probably:

enum Foo
{
  blah = 1,
  ....
  all = ~0
}

For unsigned based enum:

enum Foo : uint
{
  blah = 1,
  ....
  all = ~0u;
}
Ian Goldby
  • 5,609
  • 1
  • 45
  • 81
leppie
  • 115,091
  • 17
  • 196
  • 297
  • when I try this it says "Constant value '-1' cannot be converted to a 'uint' " – AFgone Sep 19 '11 at 08:10
  • 1
    Just cast it then, eg `unchecked((uint)~0)` – leppie Sep 19 '11 at 08:11
  • Can int.MaxValue be used? – Vladius Feb 03 '16 at 14:10
  • @Vladius: Sure, but why? :D – leppie Feb 03 '16 at 14:42
  • 3
    @Vladius: int.MaxValue has not set the sign bit (bit 31) its value is hexadecimal 0x7FFFFFFF. So only bits 0 to 30 are set. You can use -1 for signed types but not for unsigned types. Still ~0 is the best. – huha Jul 19 '16 at 11:27
  • 3
    ~0 is not good enough as you can't test for it. The combination of all options is not equal to ~0 – Rob Vermeulen Mar 06 '20 at 10:24
  • It's worth mentioning that whilst this does work here, ~0 is all 1s, even for the values you haven't assigned yet. So you can't use it for int comparison unless you have 31 flags. @realstrategos 's answer below has an accurate shortcut for all = ~(-1 << 4) in which only the bits required are set. – Tod Aug 24 '22 at 07:51
33
[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3,
    All = ~(-1 << 4)
}
realstrategos
  • 783
  • 8
  • 7
  • 1
    I like this option even better than my usual `-1` option. I was using an enum to keep track of which tasks were requested and removing the flag when the task was completed. My plan was then to use the result as the exit code. So this helps with the maintenance of the tasks enum. – Schmalls Jul 20 '14 at 05:27
  • 9
    I prefer `All = ~(~0 << 4)` because it's a little more clear. Not everyone knows that `-1` is all `1`s. – David Sherret Aug 15 '16 at 19:16
  • `None` shouldn't be `-1` ?! – akhansari Nov 28 '16 at 17:30
  • Why do you shift -1 by 4 steps? – dmitry1100 Aug 04 '20 at 12:00
  • 1
    @C0DEF52 Im willing to bet he did it to keep the consistency in layout for each value. I do the same for 0 where i set the flag equal to (0 << 0) because it makes everything look nice. – ZXYNINE Jun 29 '22 at 15:51
  • @C0DEF52 How else would you do it? -1 sets all flags to 1, shifting left 4 means you have all 1's followed by 4 0s, invert that gives you all 4 flags set. – Tod Aug 24 '22 at 07:43
  • @Tod yes I understand now but I didn't get it in the past when asked. By the way another way to set All is to unite all other flags: `All = First | Second | Third | Fourth` – dmitry1100 Sep 20 '22 at 22:58
  • Isn't this 11101111, while it should be 00001111? – Brackets Oct 29 '22 at 13:21
8
internal static class Program
{
    private static void Main()
    {
        Console.WriteLine(Foo.Everything.HasFlag(Foo.None)); // False
        Console.WriteLine(Foo.Everything.HasFlag(Foo.Baz)); // True
        Console.WriteLine(Foo.Everything.HasFlag(Foo.Hello)); // True
    }
}

[Flags]
public enum Foo : uint
{
    None = 1 << 0,
    Bar = 1 << 1,
    Baz = 1 << 2,
    Qux = 1 << 3,
    Hello = 1 << 4,
    World = 1 << 5,
    Everything = Bar | Baz | Qux | Hello | World
}

Was this what you wanted?

Scott
  • 999
  • 7
  • 13
  • 1
    but this is not regardless of other enums, when I edit or remove enums I have to change also "Everything" – AFgone Sep 19 '11 at 08:11
  • 1
    This is the correct solution. `~0` is not good enough as you can't test for it. The combination of all options is not equal to ~0. – ZorgoZ Mar 14 '18 at 10:03
5

In case someone is wondering: I needed to do the same building a Bindable enumconverter for WPF.
Since I don't know what the values mean in Reflection, I needed to manually been able to switch values (binding them to a checkbox p.e.)
There is a problem setting the value of a Flagged enum to -1 to set all the bits.
If you set it to -1 and you unflag all values it will not result in 0 because all unused bits are not unflagged.
This is wat worked best for my situation.

SomeRightEnum someRightEnum = SomeRightEnum.CanDoNothing;
Type enumType = someRightEnum.GetType();
int newValue = 0;
var enumValues = Enum.GetValues(enumType).Cast<int>().Where(e => e == 1 || e % 2 == 0);
foreach (var value in enumValues)
{
    newValue |= value;
}
Console.WriteLine(newValue);

Or if you would want an extension method:

public static class FlagExtensions
{
    public static TEnum AllFlags<TEnum>(this TEnum @enum)
        where TEnum : struct
    {
        Type enumType = typeof(TEnum);
        long newValue = 0;
        var enumValues = Enum.GetValues(enumType);
        foreach (var value in enumValues)
        {
            long v = (long)Convert.ChangeType(value, TypeCode.Int64);
            if(v == 1 || v % 2 == 0)
            {
               newValue |= v; 
            }
        }
        return (TEnum)Enum.ToObject(enumType , newValue);
    }
}
Silvermind
  • 5,791
  • 2
  • 24
  • 44
  • 1
    make it an extension method named `AllFlags` that extends the `enum` system class. then it could be used neatly `enum.AllFlags(typeof(MyEnum))` no ? – v.oddou Nov 21 '14 at 10:53
  • @v.oddou I have updated my answer with a generic extension that returns the (immutable) value. I also removed a bug to omit non-flag values. – Silvermind Nov 21 '14 at 11:47
0

I find All = ~0 more elegant, but to have more transparency starting from C# 7.0 you can use

binary literals like 0b0101010111 together with digit separators _ like 0b_0101_0101_11.

So to set all flags for the Int32 you can chose one of the following possibilities, all of them are the same:

All = unchecked((int)0b_1111_1111_1111_1111_1111_1111_1111_1111)
All = unchecked((int)0b_11111111_11111111_11111111_11111111)
All = unchecked((int)0b11111111111111111111111111111111)
Rekshino
  • 6,954
  • 2
  • 19
  • 44