Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic extension method to see if an enum contains a flag

Tags:

c#

enums

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.

like image 407
Juan Avatar asked Nov 05 '10 18:11

Juan


People also ask

What is a flag enum?

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.


2 Answers

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) --

like image 30
Justin Niessner Avatar answered Sep 23 '22 12:09

Justin Niessner


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:

  • This handles nulls
  • Does type checking
  • Converts to a ulong, and can handle any positive enum value. Microsoft cautions against the use of negative flags enumerations anyway:

    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.

like image 120
chilltemp Avatar answered Sep 23 '22 12:09

chilltemp