Reputation: 9237
Consider the following simple Flags Enum in C#:
[Flags]
public enum CountingEnum
{
Zero = 0,
One = 1 << 0,
Two = 1 << 1,
Three = Two | One,
Four = 1 << 2,
Five = Four | One,
}
If I want to know whether one value contains another, I can write a simple extension method using the bitwise logical AND (&) operator. This looks a lot like Enum.HasFlag, but I'm writing it out for a reason. This method needs to know the Enum type, and HasFlag only works on matching enum types. I want a generic solution that works across types:
public static class CountingEnumExtensions
{
public static bool Contains(this CountingEnum value, CountingEnum target)
{
return (value & target) == target;
}
}
This lends itself to a clean syntax for checking if one Flags value contains another:
if (CountingEnum.Five.Contains(CountingEnum.Four))
{
// Yep!
}
if (CountingEnum.Four.Contains(CountingEnum.Five))
{
// Nope!
}
But what if I have another Flags Enum? I could make another extension method each time I want to do this, but that isn't very sustainable. .HasFlag is also no help:
if (CountingEnum.Three.HasFlag(AnotherCountingEnum.One){
// System.ArgumentException
}
I could just manually use this everywhere, but it isn't very readable for the bitwise non-literate:
if ((SomeEnum.Value & SomeEnum.Target) == SomeEnum.Target)
{
// Dunno!
}
But is there a general solution? The following will not compile, of course, but it conveys the idea of what I'd like to have:
public static class EnumExtensions
{
public static bool Contains(this Enum value, Enum target)
{
// Cannot apply operation '&' to operands of
// type 'System.Enum' and 'System.Enum'
return (value & target) == target;
}
}
Is there a general solution to perform a bitwise logical AND against any two Flags Enum values of matching type?
Upvotes: 0
Views: 798
Reputation: 20891
If their signs are not important, you can try to unsigned integer type conversion.
public static bool Contains(this Enum value, Enum target)
{
uint y = Convert.ToUInt32(value);
uint z = Convert.ToUInt32(target)
return (y & z) == z;
}
Upvotes: 2