关于c#:如何设置枚举标志的所有位

How to set all bits of enum flag

我想知道将enum标志的所有位设置为1的通用方法。我只想有一个enum,它可以返回所有比较,而不考虑其他枚举。

而这一准则是有效的;

1
2
3
4
5
6
7
8
9
10
[Flags]
public enum SomeRightEnum : uint
{
    CanDoNothing = 0,
    CanDoSomething = 1 << 0,
    CanDoSomethingElse = 1 << 1,
    CanDoYetAnotherThing = 1 << 2,
    ...
    DoEverything = 0xFFFFFFFF
}

但是在上面的代码中,因为它是uint,所以我们设置了"f"的数目,如果它是int,它就不会工作。

因此,不管数据类型是什么(int、int64uint等),我都会欣赏将enum标志的所有位设置为1的通用方法。


最简单的可能是:

1
2
3
4
5
6
enum Foo
{
  blah = 1,
  ....
  all = ~0
}

对于基于无符号的枚举:

1
2
3
4
5
6
enum Foo : uint
{
  blah = 1,
  ....
  all = ~0u;
}


1
2
3
4
5
6
7
8
9
10
[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3,
    All = ~(-1 << 4)
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
}

这是你想要的吗?


如果有人想知道:我需要为WPF构建一个可绑定的EnumConverter。因为我不知道反射中的值是什么意思,所以我需要手动切换值(将它们绑定到复选框p.e.)
将标记枚举的值设置为-1以设置所有位时出现问题。
如果将其设置为-1,并且取消标记所有值,则不会导致0,因为所有未使用的位都没有取消标记。
这对于我的情况最有效。

1
2
3
4
5
6
7
8
9
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);

或者如果需要扩展方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);
    }
}