Помеченная консолидация Enum (обратная комбинация) с использованием LINQ

Я пытаюсь создать инверсию помеченного перечисления. Ниже приведено перечисление:

[Flags]
public enum MyType
{
  Unknown = 0,
  A = 1 << 0,
  B = 1 << 2,
  C = 1 << 3,
  D = 1 << 4,
  E = 1 << 5,
  F = 1 << 6
}

Я определил статический MyType mtGroup1 со значением (A | B). Я хотел бы сгенерировать инверсию этого, исключая Unknown.

Мое решение:

MyType t = MyType.Unknown;
foreach (var vType in Enum.GetValues(typeof(MyType)).OfType<MyType>())
{
    if ((mtGroup1 & vType) != vType)
         t = t | vType;   //Consolidates into a single enum, excluding unknown
}

Результирующее значение t равно C | D | E | F, что является желаемым результатом. Этот метод работает, но я надеялся, что существует более простой способ консолидации, как показано выше, с использованием LINQ (другие способы, отличные от LINQ, также приемлемы, если они проще).

Спасибо!


person Jon Peterson    schedule 26.07.2012    source источник


Ответы (1)


Мой проект Unconstrained Melody делает это очень просто:

MyType inverse = mtGroup1.UsedBitsInverse();

Проект содержит ряд полезных методов (многие написаны как методы расширения), которые используют «невыразимые» универсальные ограничения (те, которые понимаются компилятором C#, но не могут быть выражены в C#), чтобы ограничить параметры универсального типа типами перечисления или делегаты. Таким образом, приведенный выше код работает без упаковки — и он фактически обрабатывает все «интересные» биты типа перечисления один раз, когда этот тип используется в сочетании с Unconstrained Melody впервые, поэтому эта операция ослепительно эффективна. .

Если вы не хотите использовать Unconstrained Melody, вы можете написать свой собственный метод для поиска «используемых битов» перечисления один раз, а затем просто использовать:

MyType t = UsedBitsOfMyType & ~mtGroup1;
person Jon Skeet    schedule 26.07.2012
comment
Интересно! Мистер Скит всегда так быстр в розыгрыше - я впечатлен. Я собираюсь дать этому день или около того, чтобы другие могли отправлять ответы, которые не являются целыми библиотеками, прежде чем принять ваш ответ как лучший. - person Jon Peterson; 27.07.2012
comment
Проверьте последнюю часть: «Если вы не хотите использовать [библиотеку]…». - person John Arlen; 27.07.2012