Is there a solution for a bitwise logical AND (&) operator between two Enum values in C#

651 Views Asked by At

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?

1

There are 1 best solutions below

2
On BEST ANSWER

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;
}