【问题标题】:Extracting enum flags to list with generic method?使用通用方法提取枚举标志以列出?
【发布时间】:2018-12-28 06:31:48
【问题描述】:

意识形态

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

我的目标框架是.Net Core 2.1。我已经能够使用特定的枚举来执行此操作,但是,我想扩展此方法以接受任何类型的基于 int 的枚举,使用通用方法转换为 ListHashSet 以减少样板代码。

代码

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.

结论

我知道我将不得不使用通用方法,例如:

public static List<TEnum> EnumToList<TEnum>(TEnum value) { }

但是我完全迷失了从这里去哪里,所以非常感谢任何帮助。

【问题讨论】:

  • 那么现在的代码有什么问题呢?你的问题到底是什么?
  • 而不是EnumToList() 处理特定的enum,我希望它是一种通用方法,可以采用任何带有组合标志的枚举并将其转换为该枚举类型的List List 的成员每个都是提取的标志。
  • 那么当您将其更改为您展示的通用方法并使其使用给定类型时,发生了什么?
  • value 在 while 循环中无法转换为 int。使用 (int)value 或 (enum)Value 进行强制转换无济于事。

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


【解决方案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

【讨论】:

  • 这完全符合我的要求!我将添加一些额外的检查并对此进行扩展-但除此之外,我不确定它是否会比这更干净。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-16
相关资源
最近更新 更多