C#Enum标志比较

des*_*old 5 c# enums

鉴于以下标志,

  [Flags]
    public enum Operations
    {
        add = 1,
        subtract = 2,
        multiply = 4,
        divide = 8,
        eval = 16,
    }
Run Code Online (Sandbox Code Playgroud)

如何实现IF条件来执行每个操作?在我的尝试中,第一个条件适用于add,eval,这是正确的.然而,第一个条件也适用于减法,eval,这是不正确的.

        public double Evaluate(double input)
    {
        if ((operation & (Operations.add & Operations.eval)) == (Operations.add & Operations.eval))
            currentResult += input;
        else if ((operation & (Operations.subtract & Operations.eval)) == (Operations.subtract & Operations.eval))
            currentResult -= input;
        else
            currentResult = input;

        operation = null;

        return currentResult;
    }
Run Code Online (Sandbox Code Playgroud)

我看不出是什么问题.

Kel*_*tex 24

改变内心&|:

if ((operation & (Operations.add | Operations.eval)) == (Operations.add | Operations.eval))
Run Code Online (Sandbox Code Playgroud)

这相当于:

if( ((operation & Operations.add)==Operations.add) &&
    ((operation & Operations.eval)==Operations.eval))
Run Code Online (Sandbox Code Playgroud)

这可能更具可读性.您可能还想考虑这样的扩展:

public static bool HasFlag(this Operations op, Operations checkflag)
{
    return (op & checkflag)==checkflag;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

if(operation.HasFlag(Operations.add) && Operations.HasFlag(Operations.eval))
Run Code Online (Sandbox Code Playgroud)

这可能更具可读性.最后,您可以创建此扩展程序以获得更多乐趣:

public static bool HasAllFlags(this Operations op, params Operations[] checkflags)
{
    foreach(Operations checkflag in checkflags)
    {
        if((op & checkflag)!=checkflag)
            return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

然后你的表达可能变成:

if(operation.HasAllFlags(Operations.add, Operations.eval))
Run Code Online (Sandbox Code Playgroud)


Rya*_*rle 12

哇,我无法相信所有错误的答案..

如果你正在使用标志,理解按位数学是很重要的.在您的情况下,您有以下(对于第一个条件):

1 in binary is  00001
16 in binary is 10000

  00001
& 10000
--------
  00000
Run Code Online (Sandbox Code Playgroud)

所以,假设我们有Subtract(2)作为 operation

2 in binary is     00010
previous result is 00000

  00010
& 00000
--------
  00000
Run Code Online (Sandbox Code Playgroud)

由于之前的结果是00000任何东西,因此它将为零.所以,你的条件将始终评估为true0 == 0.

如果我们只是将其切换为OR,那么我们有以下内容:

1 in binary is  00001
16 in binary is 10000

  00001
| 10000
--------
  10001 (17)
Run Code Online (Sandbox Code Playgroud)

现在,说我们有Add (1)作为operation

1 in binary is     00001
previous result is 10001 (17)

  00001
& 10001
--------
  00001
Run Code Online (Sandbox Code Playgroud)

所以,1 & 17 => 1因此你的最终条件是(1 & ( 1 | 16 ) ) == ( 1 | 16 )=> 1 & 17 == 17=> 1 == 17=> false(仍然是假的!)

所以你真正想要的是:

((operation | Operations.add | Operations.eval) & (Operations.add | Operations.eval)) == (Operations.add | Operations.eval)
Run Code Online (Sandbox Code Playgroud)

这变成((1 | 1 | 16 ) & ( 1 | 16 )) == ( 1 | 16 )=> ( 17 & 17 ) == 17=> 17 == 17==true

这显然是不可读的,因此您应该选择将其提取到方法中(如建议的那样).但是理解为什么你的病情不正确仍然很重要.