Перечисление C# отмечает сравнение

Учитывая следующие флаги,

  [Flags]
    public enum Operations
    {
        add = 1,
        subtract = 2,
        multiply = 4,
        divide = 8,
        eval = 16,
    }

Как я мог реализовать ЕСЛИ условие выполнить каждую операцию? В моей попытке первое условие верно для, добавляют, оценка, которая корректна. Однако первое условие также верно для, вычитают, оценка, которая является неправильной.

        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;
    }

Я не вижу, какова проблема.

5
задан destructo_gold 2 April 2010 в 14:57
поделиться

4 ответа

Измените внутренние & на |:

if ((operation & (Operations.add | Operations.eval)) == (Operations.add | Operations.eval))

Это эквивалентно:

if( ((operation & Operations.add)==Operations.add) &&
    ((operation & Operations.eval)==Operations.eval))

что может быть более читабельным. Вы также можете рассмотреть расширение, подобное этому:

public static bool HasFlag(this Operations op, Operations checkflag)
{
    return (op & checkflag)==checkflag;
}

тогда вы можете сделать это:

if(operation.HasFlag(Operations.add) && Operations.HasFlag(Operations.eval))

что может быть еще более читабельным. Наконец, вы можете создать это расширение для еще большего удовольствия:

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

Тогда ваше выражение может превратиться в:

if(operation.HasAllFlags(Operations.add, Operations.eval))
24
ответ дан 18 December 2019 в 05:18
поделиться

Вау, я не могу поверить во все неправильные ответы ..

Важно понимать побитовую математику, если вы работаете с флагами. В вашем случае у вас есть следующее (для первого условия):

1 in binary is  00001
16 in binary is 10000

  00001
& 10000
--------
  00000

Итак, скажем, у нас есть Subtract (2) как операция

2 in binary is     00010
previous result is 00000

  00010
& 00000
--------
  00000

Поскольку предыдущий результат - 00000 что угодно И Буду с ней нулю. Таким образом, ваше условие всегда будет оцениваться как true , поскольку 0 == 0 .

Если мы просто переключим это на OR, то мы получим следующее:

1 in binary is  00001
16 in binary is 10000

  00001
| 10000
--------
  10001 (17)

Теперь предположим, что у нас есть Add (1) как операция

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

  00001
& 10001
--------
  00001

Итак, 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)

Это становится ((1 | 1 | 16) & (1 | 16)) == (1 | 16) => (17 & 17) == 17 => 17 == 17 == true

Это явно не читается, поэтому вам следует выбрать извлечение в метод (как предлагается). Но все же важно понять, почему ваше условие неверно.

12
ответ дан 18 December 2019 в 05:18
поделиться

Попробуйте следующее:

   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;
}
1
ответ дан 18 December 2019 в 05:18
поделиться

Причина сбоя операции в том, что у вас неправильное выражение. (Operations.add & Operations.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;
}
1
ответ дан 18 December 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: