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

C# 如何设置枚举标志的所有位,c#,enums,enum-flags,C#,Enums,Enum Flags,我想知道一种将enum标志的所有位设置为1的通用方法。 我只希望有一个enum,它返回所有比较,而不考虑其他枚举 这个代码是有效的 [Flags] public enum SomeRightEnum : uint { CanDoNothing = 0, CanDoSomething = 1 << 0, CanDoSomethingElse = 1 << 1, CanDoYetAnotherThing = 1 << 2,

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

这个代码是有效的

[Flags]
public enum SomeRightEnum : uint
{
    CanDoNothing = 0,
    CanDoSomething = 1 << 0,
    CanDoSomethingElse = 1 << 1,
    CanDoYetAnotherThing = 1 << 2,
    ...
    DoEverything = 0xFFFFFFFF 
}
[标志]
公共枚举SomeRightEnum:uint
{
CanDoNothing=0,
CandoMething=1
内部静态类程序
{
私有静态void Main()
{
Console.WriteLine(Foo.Everything.hasvag(Foo.None));//False
Console.WriteLine(Foo.Everything.hasvag(Foo.Baz));//True
Console.WriteLine(Foo.Everything.hasvag(Foo.Hello));//True
}
}
[旗帜]
公共枚举Foo:uint
{
无=1最简单的可能是:

enum Foo
{
  blah = 1,
  ....
  all = ~0
}
对于基于无符号的枚举:

enum Foo : uint
{
  blah = 1,
  ....
  all = ~0u;
}

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

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);
SomeRightEnum SomeRightEnum=SomeRightEnum.CanDoNothing;
类型enumType=someRightEnum.GetType();
int newValue=0;
var enumValues=Enum.GetValues(enumType).Cast()。其中(e=>e==1 | | e%2==0);
foreach(枚举值中的变量值)
{
newValue |=值;
}
Console.WriteLine(newValue);
或者,如果需要扩展方法:

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);
    }
}
公共静态类扩展
{
公共静态TEnum AllFlags(此TEnum@enum)
其中TEnum:struct
{
类型enumType=typeof(TEnum);
长newValue=0;
var enumValues=Enum.GetValues(enumType);
foreach(枚举值中的变量值)
{
long v=(long)Convert.ChangeType(值,TypeCode.Int64);
如果(v==1 | | v%2==0)
{
新值|=v;
}
}
return(TEnum)Enum.ToObject(enumType,newValue);
}
}
[标志]
公共枚举髓鞘
{
无=0,

First=1 Hmmm。枚举的目的是描述互斥的选项。您似乎将它们用作一组位掩码的简写。@AFgone您正在使用枚举右侧的[Flags]属性?@Oli The[Flags]枚举上的属性就是为了这个目的而设计的。@Bernie White:Flags属性纯粹是装饰性的,你可以不使用它而使用“Flags”。@Bernie是的,我编辑过,只是放弃复制它。当我尝试这个时,它说“常量值”-1“不能转换为“uint”,然后强制转换它,例如
取消选中((uint)~0)
可以使用int.MaxValue吗?@Vladius:int.MaxValue没有设置符号位(位31)它的值是十六进制0x7FFFFF。因此只设置了位0到30。您可以将-1用于有符号类型,但不能用于无符号类型。仍然~0是最好的。~0不够好,因为您无法对其进行测试。所有选项的组合不等于~0,但这与其他枚举无关,当我编辑或删除枚举时,我还必须更改“一切"这是正确的解决方案。
~0
不够好,因为您无法测试它。所有选项的组合不等于~0。我甚至比我通常的
-1
选项更喜欢此选项。我使用枚举来跟踪请求了哪些任务,并在任务完成时删除该标志。我的计划是使用结果作为退出代码。因此这有助于任务枚举的维护。我更喜欢
All=~(~0
None
不应该是
-1
?!为什么要将-1移动4步?将其作为扩展
enum
系统类的扩展方法,名为
AllFlags
。这样就可以灵活地使用
enum.AllFlags(typeof(MyEnum))
no?@v.oddou我已使用返回(不可变)值的通用扩展名更新了我的答案。我还删除了一个忽略非标志值的错误。
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);
    }
}
[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3,
    All = ~(-1 << 4)
}