C#将flag枚举类型的变量中的集合标志转换为整数数组

C#将flag枚举类型的变量中的集合标志转换为整数数组,c#,linq,string,enumeration,C#,Linq,String,Enumeration,我提出了这段代码,它转换Flag枚举类型变量中的set标志,并将set标志作为整数返回。 我想知道这是不是最好的办法 枚举示例: [Flags] enum Status { None = 0x0, Active = 0x1, Inactive = 0x2, Canceled = 0x4, Suspended = 0x8 } 我就是这样使用它的: Status filterStatus = Status.Suspended | Status.Canceled; int[] f

我提出了这段代码,它转换Flag枚举类型变量中的set标志,并将set标志作为整数返回。 我想知道这是不是最好的办法

枚举示例:
[Flags]
enum Status {
  None = 0x0,
  Active = 0x1,
  Inactive = 0x2,
  Canceled = 0x4,
  Suspended = 0x8
}
我就是这样使用它的:

Status filterStatus = Status.Suspended | Status.Canceled;

int[] filterFlags = filterStatus.toIntArray();

foreach (int flag in filterFlags) {
   Console.WriteLine("{0}\n", flag);
}
它将输出:

4
8
如您所见,为了完成此任务,我将执行以下操作:

  • 将变量转换为字符串。它的输出类似于:暂停、取消
  • 将该字符串拆分为字符串数组:{“挂起”、“取消”}
  • 使用Enum.Parse将该字符串转换为枚举值
  • 将值强制转换为整数
  • 将IEnumerable转换为int[]

  • 这是可行的,但我不认为这是最好的方法。有什么改进这段代码的建议吗?

    只需转换为int,然后打印出各个位

    int x = (int)o
    List<int> flags = new List<int>();
    for(int i = 1; i < (1 << 30); i <<= 1)
        if(x & i != 0)
            flags.Add(i);
    return flags;
    
    intx=(int)o
    列表标志=新列表();
    
    对于(int i=1;i<(1嗯,您可以用对的调用来替换步骤1-3,然后使用按位
    &
    运算符来测试哪些是在您的值中设置的。这将比使用字符串快得多

    此方法将支持超过一个位宽的标志。如果所有位都是独立的,则只需。

    即可使其保持linq

    var flags = Enum.GetValues(typeof(Status))
                    .Cast<int>()
                    .Where(f=> f & o == f)
                    .ToList();
    
    var flags=Enum.GetValues(typeof(Status))
    .Cast()
    其中(f=>f&o==f)
    .ToList();
    
    这种方法的一个缺点是它将包括聚合枚举值。例如:

    [Flags]
    public enum Status
    {
        None = 0,
        One = 1,
        Two = 2,
        All = One | Two,
    }
    
    var flags = Enum.GetValues(typeof(Status))
                    .Cast<int>()
                    .Where(f=> f & o == f)
                    .ToList();
    
    [标志]
    公共枚举状态
    {
    无=0,
    1=1,
    二等于二,
    全部=一|二,
    }
    var flags=Enum.GetValues(typeof(Status))
    .Cast()
    其中(f=>f&o==f)
    .ToList();
    

    这里的
    标志将有
    1,2,3
    ,而不仅仅是
    1,2

    不是所有
    enum
    类型都基于
    int
    作为基础类型,因此强制转换可能会失败。@Ben-这是一个很好的观点,并且会影响我在答案中的解决方案。最好的想法可能是认识到这不是一个通用的解决方案,但这是一个特定的解决方案,当您了解正在使用的枚举时可以应用。您可以使用基础类型的泛型,但我认为这在大多数情况下都是过分的。它确实不是一个通用的解决方案,并且只适用于基础类型为System.Int32的枚举。此外,枚举中的所有值都是因此,Steve Mitcham的解决方案可以工作,同时保持类似LINQ。应该是
    Where(f=>f&o==f)<代码> F.O.<代码>的结果不限于<代码> f>代码>和<代码> 0代码>。例如,考虑<代码>系统.Windows。窗体。键< /代码> EnUM。@本:你是对的。我也承认了你关于“代码< EnUM <代码> > <代码> ULUN < /代码>的观点。我删除了我的误导性评论。(我发帖子的时候已经很晚了,我显然没有思考清楚!)
    
    [Flags]
    public enum Status
    {
        None = 0,
        One = 1,
        Two = 2,
        All = One | Two,
    }
    
    var flags = Enum.GetValues(typeof(Status))
                    .Cast<int>()
                    .Where(f=> f & o == f)
                    .ToList();