如何从枚举值获取标志?

xnp*_*xnp 0 c# enum-flags

尝试从枚举值获取所有可能标志的数组,例如 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;
}
Run Code Online (Sandbox Code Playgroud)

……但这似乎有点浪费。这可以更有效地完成吗?

Jak*_*rtz 6

您可以简单地将 的所有可能值过滤MyEnum为 中的值modKey

internal static MyEnum[] GetFlags(this MyEnum modKey)
{
    return Enum.GetValues(typeof(MyEnum))
        .Cast<MyEnum>()
        .Where(v => modKey.HasFlag(v))
        .ToArray();
}
Run Code Online (Sandbox Code Playgroud)

编辑

根据下面的注释,如果指定了组合,该方法应该只返回组合,而不是所有设置的标志。

解决方案是从最高的标志开始循环遍历枚举中设置的所有标志。在每次迭代中,我们必须向结果添加一个标志,并将其从迭代枚举中删除,直到它为空:

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();
}
Run Code Online (Sandbox Code Playgroud)