我想出了这段代码,它在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
正如您所看到的,为了完成这项工作,我正在做以下事情:
它有效,但我认为这不是最好的方法。有任何改进这段代码的建议吗?
答案 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();
此处flags
将1, 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。