C#:检查一组枚举值的最佳方法是什么?

Geo*_*uer 9 c# math enums

假设你有 enum MyEnum {A = 0, B = 1, C = 2, D = 4, E = 8, F = 16};

在某些时候,您有一个函数将检查MyEnum的实例,如果它是C,D或F则返回true

bool IsCDF(MyEnum enumValue) 
{
  return //something slick
}
Run Code Online (Sandbox Code Playgroud)

我记得有一些非常光滑的方法来进行位移和预先形成这种操作,比一堆三元if语句读取方式更好但是对于我的生活我不记得它是什么.

谁知道?

Mag*_*nus 22

bool IsCDF(MyEnum enumValue) 
{
  return new[]{MyEnum.C, MyEnum.D, MyEnum.F}.Contains(enumValue);
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*ams 19

如果将其[Flags]设为枚举,则可以为每个枚举值分配不同的位值(1,2,4,8,1 ...).然后,您可以使用按位运算来确定值是否是一组可能值中的一个.

所以,看看它是C,D还是F:

bool IsCDF(MyEnum enumValue)
{
    return ((enumValue & (MyEnum.C | MyEnum.D | MyEnum.F)) != 0);
}
Run Code Online (Sandbox Code Playgroud)

或使用HasFlag()(效率较低但更易读):

bool IsCDF(MyEnum enumValue)
{
    return enumValue.HasFlag(MyEnum.C | MyEnum.D | MyEnum.F);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这不适用于值0(在您的示例中为'A'),并且必须注意所有枚举值都会解析为唯一位值(即非零幂的2).

这种方法的优点是:

  • 它通常需要执行一个CPU指令/周期,而执行三个单独的"if"检查将需要3个或更多指令(取决于您的目标平台).
  • 您可以将要测试的值集作为枚举值(单个整数)传递,而不是需要使用枚举值列表.
  • 你可以通过按位运算做很多其他有用的事情,这对普通的数值/比较方法来说是笨重而缓慢的.

方便提示: 在定义[Flags]枚举时,使用left-shift(<<)使位值更清晰(并且更难以出错),尤其是对于高阶位:

[Flags]
enum MyEnum
{
    A = 1 << 0,     // Equivalent to 1
    B = 1 << 1,     // Equivalent to 2
    C = 1 << 2,     // Equivalent to 4
    D = 1 << 3,     // Equivalent to 8
    …
    Big = 1 << 26,  // Equivalent to 67108864
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 5

我可能会使用无约束旋律作为保持整洁的一种方式:

if (value.HasAny(MyEnum.C | MyEnum.D | MyEnum.E))
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

我可能会将"C,D或E"位提取到一个命名常量中 - 可能在枚举本身中,如果它有意义: