I need to detect if a flag is set within an enum value, which type is marked with the Flag attribute.
Usually it is made like that:
(value & flag) ==
This should do the job for enum
types with any underlying types:
public static bool IsSet(this T value, T flags) where T : struct
{
return (Convert.ToInt64(value) & Convert.ToInt64(flags)) ==
Convert.ToInt64(flags);
}
Convert.ToInt64
is used because a 64-bit integer is the "widest" integral type possible, to which all enum values can be cast (even ulong
). Note that It seems that it is not valid in C#, but it is in general valid in CIL/for the CLR.char
is not a valid underlying type.
Also, you can't enforce a generic type constraint for enums (i.e. where T : struct
); the best you can do is use where T : struct
to enforce T
to be a value type, and then optionally perform a dynamic check to ensure that T
is an enum type.
For completeness, here is my very brief test harness:
static class Program
{
static void Main(string[] args)
{
Debug.Assert(Foo.abc.IsSet(Foo.abc));
Debug.Assert(Bar.def.IsSet(Bar.def));
Debug.Assert(Baz.ghi.IsSet(Baz.ghi));
}
enum Foo : int
{
abc = 1,
def = 10,
ghi = 100
}
enum Bar : sbyte
{
abc = 1,
def = 10,
ghi = 100
}
enum Baz : ulong
{
abc = 1,
def = 10,
ghi = 100
}
}