提取枚举标志以使用通用方法列出?
Extracting enum flags to list with generic method?
意识形态
我正在尝试从值中提取枚举标志并将它们转换为 List
或 HashSet
并排除 0 (None)。
我的目标框架是 .Net Core 2.1
。我已经能够使用特定的枚举来执行此操作,但是,我想扩展此方法以接受任何类型的基于 int 的枚举,使用通用方法转换为 List
或 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.
结论
我知道我将不得不使用通用方法,例如:
public static List<TEnum> EnumToList<TEnum>(TEnum value) { }
但我完全不知道从这里去哪里,所以非常感谢任何帮助。
也许这个
给定
[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
免责声明:显然需要尽职调查和容错
意识形态
我正在尝试从值中提取枚举标志并将它们转换为 List
或 HashSet
并排除 0 (None)。
我的目标框架是 .Net Core 2.1
。我已经能够使用特定的枚举来执行此操作,但是,我想扩展此方法以接受任何类型的基于 int 的枚举,使用通用方法转换为 List
或 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.
结论
我知道我将不得不使用通用方法,例如:
public static List<TEnum> EnumToList<TEnum>(TEnum value) { }
但我完全不知道从这里去哪里,所以非常感谢任何帮助。
也许这个
给定
[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
免责声明:显然需要尽职调查和容错