Извлечение перечислимых флагов в список с помощью общего метода - PullRequest
0 голосов
/ 28 декабря 2018

Идеология

Я пытаюсь извлечь флаги перечисления из значения и преобразовать их в List или HashSet с исключением 0 (нет).

Framework Я являюсьтаргетинг составляет .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 Ответ

0 голосов
/ 28 декабря 2018

Может быть, это

Дано

[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

Отказ от ответственности : Очевидно, требуется должная осмотрительность и отказоустойчивость

Полная демонстрация здесь

...