简体   繁体   English

如何设置枚举标志的所有位

[英]How to set all bits of enum flag

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.我想知道将enum标志的所有位设置为 1 的通用方法。我只想有一个enum ,它返回所有比较,而不考虑其他枚举。

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 .但是在上面的代码中,因为它是 uint 我们设置了“F”的数量,如果它是int它将不起作用。

So I'll appreciate a generic way of setting all bits of enum flag to 1, regardless of the datatype ( i nt, int64 , uint etc)因此,无论数据类型如何( i nt、 int64uint等),我都会欣赏将enum标志的所有位设置为 1 的通用方法

Easiest is probably: 最简单的可能是:

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

For unsigned based enum: 对于基于unsigned的枚举:

enum Foo : uint
{
  blah = 1,
  ....
  all = ~0u;
}
[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3,
    All = ~(-1 << 4)
}
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? 这是你想要的吗?

In case someone is wondering: I needed to do the same building a Bindable enumconverter for WPF. 如果有人想知道:我需要为WPF构建一个Bindable enumconverter。
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 pe) 由于我不知道反射中值的含义,我需要手动切换值(将它们绑定到复选框pe)
There is a problem setting the value of a Flagged enum to -1 to set all the bits. 将Flagged枚举的值设置为-1以设置所有位时出现问题。
If you set it to -1 and you unflag all values it will not result in 0 because all unused bits are not unflagged. 如果将其设置为-1并且取消标记所有值,则不会导致0,因为所有未使用的位都不会被标记。
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);
    }
}

I find All = ~0 more elegant, but to have more transparency starting from C# 7.0 you can use我发现All = ~0更优雅,但从C# 7.0开始,您可以使用更多的透明度

binary literals like 0b0101010111 together with digit separators _ like 0b_0101_0101_11 .0b_0101_0101_11这样的二进制文字和数字分隔符_0b0101010111

So to set all flags for the Int32 you can chose one of the following possibilities, all of them are the same:因此,要为Int32设置所有标志,您可以选择以下可能性之一,它们都是相同的:

All = unchecked((int)0b_1111_1111_1111_1111_1111_1111_1111_1111)
All = unchecked((int)0b_11111111_11111111_11111111_11111111)
All = unchecked((int)0b11111111111111111111111111111111)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM