Как получить не содержащие флаги

2

У меня есть флаги перечисления. Как получить все комбинации флагов, которые не содержат конкретного?

[Flags]
public enum TestEnum
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}

public static IEnumerable<Enum> AllNotContaining(this Enum value)
{....}

Например, TestEnum.A.AllNotContaining() должен возвращать {2, 4, 6, 8, 10, 12, 14}.

  • 1
    Так что если value = TestEnum.A | TestEnum.C вы хотите, чтобы ваша функция возвращала { TestEnum.B, TestEnum.D } ?
  • 0
    Пример TestEnum.A.AllNotContained () return {2, 4, 8, 6, 10, 12, 14}
Показать ещё 5 комментариев
Теги:
enums
flags

3 ответа

3

Шаг 1, используйте двоичный NOT:

var notUsedBits = ~ value;

Но это установит все 32 бита, которые не были использованы.

Таким образом, вы, вероятно, захотите получить маску:

[Flags]
public enum TestEnum
{
    A = 1,
    B = 2,
    C = 4,
    D = 8,    
    All = A|B|C|D,  // or compute this inside the method    
}

и тогда метод становится

// untested
public static TestEnum AllNotContaining(this TestEnum value)
{
    return ~ value & TestEnum.All;
}

это не возвращает IEnumerable, но это странно (и неэффективно) для перечисления Flags в любом случае.

1

Я не пытался отполировать код ниже, но вы должны получить общую идею:

  public static IEnumerable<int> AllNotContaining<T>(this T value)
    // where T : Enum  (as of C# 7.3).
  {
    // Determine upper bound of values to check.
    // E.g. for your test enum, the maximum value is 8 so we need to check up to 15.
    var values = Enum.GetValues(typeof(T)).Cast<int>();
    int max = values.Max() * 2 - 1;

    // Test all values to see if the given flag is present. If not, return it.
    for(int i = 0; i <= max; ++i)
    {
      // Possibly also: if( ((Enum)i).HasFlags(value))
      if((max & Convert.ToInt32(value)) == 0)
      {
        yield return i;
      }
    }
  }
0

Попробуйте вот так:

public static IEnumerable<TestEnum> AllNotContaining(this TestEnum value)
{
    return Enum.GetValues(typeof(TestEnum)).Cast<TestEnum>().Where(x => x != value).AsEnumerable();
}
  • 0
    != недостаточно для перечисления Flags - рассмотрим (A|C).AllNotContaining()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню