提取枚举标志以泛型方法列出?

时间:2018-12-28 06:31:49

标签: c# list generics enums .net-core-2.1

意识形态

我正在尝试从一个值中提取枚举标志,并将其转换为ListHashSet,但排除0(无)。

我定位的框架是.Net Core 2.1。我已经可以使用特定的枚举来执行此操作,但是,我想扩展此方法以接受使用通用方法转换为List或{{1}的基于int的任何枚举},以减少样板代码。

代码

HashSet

结果

public enum Numbers
{
    None = 0,
    One  = 1,
    Two  = 2,
    Four = 4
}

public enum Teams
{
    None       = 0,
    Stars      = 1,
    Blackhawks = 2,
    Penguins   = 4,
    Devils     = 8
}

public static List<Numbers> EnumToList(Numbers n)
{
    List<Numbers> numberList = new List<Numbers>();

    // Extract values until we hit None / 0.
    while (n != 0)     // Originally: (n != Numbers.None)
    {
        foreach (Numbers i in Enum.GetValues(typeof(Numbers)))
        {
            if (n == 0)
                break;  // Prevent excess looping.

            if ((n & i) == i && i != Numbers.None)
            {   // Found a valid item.
                numberList.Add(i);  
                n &= ~i;    // Remove the value.
            }
        }
    }

    return numberList;
}

static void Main(string[] args)
{
    Numbers nums = Numbers.One | Numbers.Four;

    List<Numbers> items = EnumToList(nums);
    if (items.Count > 0)
    {
        foreach (Numbers n in items)
        {
            Console.WriteLine($"Extracted Value: {Enum.GetName(typeof(Numbers), n)}");
        }
    }

    Console.WriteLine("Press enter to exit.");
    Console.ReadLine();
}

所需的能力和结果

通过同一函数传递类型Extracted Value: One Extracted Value: Four Press enter to exit. 的标志以获取列表。

Teams

结果:

Teams t = Teams.Stars | Teams.Blackhawks | Teams.Devils;
List<Teams> teams = EnumToList(t);

结论

我知道我将必须使用通用方法,例如:

Extracted Value: Stars
Extracted Value: Blackhawks
Extracted Value: Devils
Press enter to exit.

但是我完全不知道该从哪里去,所以我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

也许是

给予

[Flags]
public enum TestEnum
{
    None = 0,
    AA = 1,
    BB = 2,
    CC = 4,
    DD = 8,
}

方法

public static IEnumerable<T> EnumerateMask<T>(Enum mask)
    => Enum.GetValues(typeof (T))
           .Cast<Enum>()
           .Where(mask.HasFlag)
           .Cast<T>()
           .Skip(1);

用法

var mask = TestEnum.AA | TestEnum.None | TestEnum.DD;

foreach (var value in EnumerateMask<TestEnum>(mask))
    Console.WriteLine(value);

输出

AA
DD

免责声明 :显然,必须进行尽职调查和容错

Full Demo Here