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

时间:2010-07-08 21:53:49

标签: c# linq string enumeration

我想出了这段代码,它在Flag Enumeration类型的变量中转换set标志,并将set flags作为整数返回。 我想知道这是否是最佳方法。

枚举示例:

[Flags]
enum Status {
  None = 0x0,
  Active = 0x1,
  Inactive = 0x2,
  Canceled = 0x4,
  Suspended = 0x8
}

将set flags转换为我想出的int数组的扩展方法:

public static class Extensions
{
    public static int[] ToIntArray(this System.Enum o) 
    {
        return o.ToString()
            .Split(new string[] { ", " }, StringSplitOptions.None)
            .Select(i => (int)Enum.Parse(o.GetType(), i))
            .ToArray();
    }
}

这就是我使用它的方式:

Status filterStatus = Status.Suspended | Status.Canceled;

int[] filterFlags = filterStatus.toIntArray();

foreach (int flag in filterFlags) {
   Console.WriteLine("{0}\n", flag);
}

将输出:

4
8

正如您所看到的,为了完成这项工作,我正在做以下事情:

  1. 将变量转换为字符串。它输出的内容如下:Suspended,Cancelled
  2. 将该字符串拆分为字符串数组:{“Suspended”,“Canceled”}
  3. 使用Enum.Parse将该字符串转换为枚举值。
  4. 将值转换为整数。
  5. 将IEnumerable转换为int []。
  6. 它有效,但我认为这不是最好的方法。有任何改进这段代码的建议吗?

3 个答案:

答案 0 :(得分:11)

保持类似linq的

var flags = Enum.GetValues(typeof(Status))
                .Cast<int>()
                .Where(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();

此处flags1, 2, 3,而不只是1, 2

答案 1 :(得分:3)

只需转换为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;

答案 2 :(得分:0)

嗯,您可以通过拨打Enum.GetValues来替换步骤1-3。然后使用按位&运算符来测试在您的值中设置了哪些。这比使用字符串要快得多。

此方法将支持多个位宽的标志。如果所有位都是独立的,只需do what Anon said