尝试从枚举值中获取所有可能的标志数组,例如3到数组{1,2}。
我有一个扩展名
internal static MyEnum[] GetFlags(this MyEnum modKey)
{
string[] splitStr = modKey.ToString().Split(new string[1] { ", " }, StringSplitOptions.RemoveEmptyEntries);
MyEnum[] flags = new MyEnum[splitStr.Length];
for (int i = 0; i < splitStr.Length; i++)
{
flags[i] = (MyEnum)Enum.Parse(typeof(MyEnum), splitStr[i]);
}
return flags;
}
......但这个目的似乎有点浪费。这可以更有效地完成吗?
答案 0 :(得分:3)
您只需将MyEnum
的所有可能值过滤为modKey
中的值:
internal static MyEnum[] GetFlags(this MyEnum modKey)
{
return Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>()
.Where(v => modKey.HasFlag(v))
.ToArray();
}
修改强>
根据下面的注释,如果指定了组合,该方法应仅返回组合,而不是所有标志集。
解决方案是循环遍历从最高标记开始的枚举中设置的所有标志。在每次迭代中,我们必须在结果中添加一个标志,并将其从迭代的枚举中删除,直到它为空:
internal static MyEnum[] GetFlags(this MyEnum modKey)
{
List<MyEnum> result = new List<MyEnum>();
while (modKey != 0)
{
var highestFlag = Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>()
.OrderByDescending(v => v)
.FirstOrDefault(v => modKey.HasFlag(v));
result.Add(highestFlag);
modKey ^= highestFlag;
}
return result.ToArray();
}
答案 1 :(得分:1)
假设你的MyEnum有一个Flags属性,为了测试是否设置了一个标志,(标准?)方式是执行二进制&amp;在你的价值和你要测试的旗帜之间: 所以这样的事情应该有效:
internal static MyEnum[] GetFlags(this MyEnum modKey)
{
List<MyEnum> flags = new List<MyEnum>();
foreach (var flag in Enum.GetValues(typeof(MyEnum)))
{
if (modKey & flag == flag)
flags.Add((MyEnum)flag);
}
return flags.ToArray();
}
如果您使用.Net 4或更高版本,则可以使用HasFlag
if (modKey.HasFlag((MyEnum)flag))
...