C #: Best way to check Enum value set?

suppose you have enum MyEnum {A = 0, B = 1, C = 2, D = 4, E = 8, F = 16};

At some point, you have a function that will check the MyEnum instance and return true if it is C, D or F

 bool IsCDF(MyEnum enumValue) { return //something slick } 

I remember that there was some really smooth way to do a bit offset and transform this operation, which reads better than a bunch of three-dimensional statements, but for my life I can’t remember what it is.

Somebody knows?

+7
source share
6 answers

If you do this by listing [Flags], you can assign a different bit value (1, 2, 4, 8, 16 ...) for each value listed. You can then use a bitwise action to determine if a value is one of many possible values.

So, to make sure it is C, D or F:

 bool IsCDF(MyEnum enumValue) { return((enumValue & (MyEnum.C | MyEnum.D | MyEnum.F)) != 0); } 

Note that this will not work for a value of 0 (in your example, β€œA”), and you should be careful that all enumeration values ​​allow unique bit values ​​(that is, non-zero permissions for two).

The advantages of this approach are as follows:

  • typically, a single CPU command will be executed, while three separate if-checks will require 3 or more instructions (depending on your target platform).
  • You can pass a set of values ​​that you want to test using an enumeration value (integer) instead of having to use lists of enumeration values.
  • You can do many other useful things with bitwise operations that would be awkward and slow with conventional numerical / comparative approaches.
+15
source
 bool IsCDF(MyEnum enumValue) { return new[]{MyEnum.C, MyEnum.D, MyEnum.F}.Contains(enumValue); } 
+17
source

I would use Unconstrained Melody as a way to keep things going :

 if (value.HasAny(MyEnum.C | MyEnum.D | MyEnum.E)) { ... } 

I would probably extract the β€œC, D or E” bit into a named constant - perhaps in the enum itself, if that matters:

+5
source

You might be thinking of FlagsAttribute . Take a look here and here for some examples.

You can use the Enum.HasFlag Method

+2
source

Perhaps this extension class is useful for you:

 public static class Flags { /// <summary> /// Checks if the type has any flag of value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public static bool HasAny<T>(this System.Enum type, T value) { try { return (((int) (object) type & (int) (object) value) != 0); } catch { return false; } } /// <summary> /// Checks if the value contains the provided type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public static bool Has<T>(this System.Enum type, T value) { try { return (((int)(object)type & (int)(object)value) == (int)(object)value); } catch { return false; } } /// <summary> /// Checks if the value is only the provided type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public static bool Is<T>(this System.Enum type, T value) { try { return (int)(object)type == (int)(object)value; } catch { return false; } } /// <summary> /// Appends a value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public static T Add<T>(this System.Enum type, T value) { try { return (T)(object)(((int)(object)type | (int)(object)value)); } catch (Exception ex) { throw new ArgumentException( string.Format( "Could not append value from enumerated type '{0}'.", typeof(T).Name ), ex); } } /// <summary> /// Appends a value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public static void AddTo<T>(this System.Enum type, ref T value) { try { value = (T)(object)(((int)(object)type | (int)(object)value)); } catch (Exception ex) { throw new ArgumentException( string.Format( "Could not append value from enumerated type '{0}'.", typeof(T).Name ), ex); } } /// <summary> /// Removes the value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public static T Remove<T>(this System.Enum type, T value) { try { return (T)(object)(((int)(object)type & ~(int)(object)value)); } catch (Exception ex) { throw new ArgumentException( string.Format( "Could not remove value from enumerated type '{0}'.", typeof(T).Name ), ex); } } /// <summary> /// Removes the value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="type"></param> /// <param name="value"></param> /// <returns></returns> public static void RemoveFrom<T>(this System.Enum type, ref T value) { try { value = (T)(object)(((int)(object)type & ~(int)(object)value)); } catch (Exception ex) { throw new ArgumentException( string.Format( "Could not remove value from enumerated type '{0}'.", typeof(T).Name ), ex); } } } 
+1
source
 return (enumValue & MyEnum.C == MyEnum.C) || (enumValue & MyEnum.D == MyEnum.D) || (enumValue & MyEnum.F == MyEnum.F); 
0
source

All Articles