Reputation: 111
I have enum flags. How to get all combinations of flags that do not contain a specific one?
[Flags]
public enum TestEnum
{
A = 1,
B = 2,
C = 4,
D = 8
}
public static IEnumerable<Enum> AllNotContaining(this Enum value)
{....}
For example, TestEnum.A.AllNotContaining()
should return {2, 4, 6, 8, 10, 12, 14}
.
Upvotes: 2
Views: 990
Reputation: 9232
I haven't tried to polish the code below, but you should get the general idea:
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;
}
}
}
Upvotes: 1
Reputation: 3113
Try like this:
public static IEnumerable<TestEnum> AllNotContaining(this TestEnum value)
{
return Enum.GetValues(typeof(TestEnum)).Cast<TestEnum>().Where(x => x != value).AsEnumerable();
}
Upvotes: 0
Reputation: 273774
Step 1, use the binary NOT:
var notUsedBits = ~ value;
But this will set all of the 32 bits that were not used.
So you will probably want a mask:
[Flags]
public enum TestEnum
{
A = 1,
B = 2,
C = 4,
D = 8,
All = A|B|C|D, // or compute this inside the method
}
and then the method becomes
// untested
public static TestEnum AllNotContaining(this TestEnum value)
{
return ~ value & TestEnum.All;
}
this does not return an IEnumerable but that is weird (and inefficient) for a Flags enum anyway.
Upvotes: 4