Considering this:
[Flags] public enum MyEnum { One = 1, Two = 2, Four = 4, Eight = 8 } public static class FlagsHelper { public static bool Contains(this MyEnum keys, MyEnum flag) { return (keys & flag) != 0; } }
Is it possible to write a generic version of Contains that would work for any enum
and not just MyEnum
?
Edit:
This would be my version after reading your answers:
public static bool Contains(this Enum keys, Enum flag) { ulong keysVal = Convert.ToUInt64(keys); ulong flagVal = Convert.ToUInt64(flag); return (keysVal & flagVal) == flagVal; }
Just realized is a bad idea to check the way I was checking (return (keys & flag) != 0;
), because the flag
parameter might be actually several flags and the common sense thing to do is return true only if keys
contains all of them. Also, I wouldn't check for null values or even make sure they are the same type. I might want to use different types.
The idea of Enum Flags is to take an enumeration variable and allow it hold multiple values. It should be used whenever the enum represents a collection of flags, rather than representing a single value. Such enumeration collections are usually manipulated using bitwise operators.
Not sure if you're using .NET 4.0 or not, but it comes with the static method Enum.HasFlags()
.
-- Code Removed (the accepted solution has it already) --
I based this method off of a bunch of SO & Google searches, and a by using reflector to see what MS did for the .NET 4 HasFlags method.
public static class EnumExt { /// <summary> /// Check to see if a flags enumeration has a specific flag set. /// </summary> /// <param name="variable">Flags enumeration to check</param> /// <param name="value">Flag to check for</param> /// <returns></returns> public static bool HasFlag(this Enum variable, Enum value) { if (variable == null) return false; if (value == null) throw new ArgumentNullException("value"); // Not as good as the .NET 4 version of this function, but should be good enough if (!Enum.IsDefined(variable.GetType(), value)) { throw new ArgumentException(string.Format( "Enumeration type mismatch. The flag is of type '{0}', was expecting '{1}'.", value.GetType(), variable.GetType())); } ulong num = Convert.ToUInt64(value); return ((Convert.ToUInt64(variable) & num) == num); } }
Notes:
Use caution if you define a negative number as a flag enumerated constant because many flag positions might be set to 1, which might make your code confusing and encourage coding errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With