Извлечение перечислимых флагов в список с помощью универсального метода?
идеология
Я пытаюсь извлечь флаги перечисления из значения и преобразовать их в List
или же HashSet
с 0 (нет) исключается.
Структура, на которую я нацеливаюсь, .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) { }
Но я полностью потерян, куда идти отсюда, поэтому любая помощь очень ценится.
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
Отказ от ответственности: очевидно, должной осмотрительности и отказоустойчивости требуется