У меня есть флаги перечисления. Как получить все комбинации флагов, которые не содержат конкретного?
[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, используйте двоичный 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 в любом случае.
Я не пытался отполировать код ниже, но вы должны получить общую идею:
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;
}
}
}
Попробуйте вот так:
public static IEnumerable<TestEnum> AllNotContaining(this TestEnum value)
{
return Enum.GetValues(typeof(TestEnum)).Cast<TestEnum>().Where(x => x != value).AsEnumerable();
}
!=
недостаточно для перечисления Flags - рассмотрим (A|C).AllNotContaining()
value = TestEnum.A | TestEnum.C
вы хотите, чтобы ваша функция возвращала{ TestEnum.B, TestEnum.D }
?