C# как использовать enum с switch

Я не могу понять, как использовать переключатели в сочетании с перечислением. Подскажите, пожалуйста, что я делаю не так и как это исправить? Я должен использовать перечисление, чтобы сделать базовый калькулятор.

public enum Operator
{
    PLUS, MINUS, MULTIPLY, DIVIDE
}

public double Calculate(int left, int right, Operator op)
{

    int i = (int) op;

    switch(i)
    {
        case 0:
        {
            return left + right;
        }

        case 1:
        {
            return left - right;
        }

        case 2:
        { 
            return left * right;
        }

        case 3:
        {
            return left / right;
        }

        default:
        {
            return 0.0;
        }
    }
}

Конечный результат должен быть примерно таким:

Console.WriteLine("The sum of 5 and 5 is " + Calculate(5, 5, PLUS))
Output: The sum of 5 and 5 is 10

Ребята, скажите, пожалуйста, как я все испортил?

10 ответов

Решение

Вам не нужно конвертировать его

switch(op)
{
     case Operator.PLUS:
     {

     }
}

Кстати, используйте скобки

Поскольку в C# 8.0 появилось новое выражение переключения для перечислений, вы можете сделать это еще более элегантно:

public double Calculate(int left, int right, Operator op) =>
            op switch 
        {
            Operator.PLUS => left + right,
            Operator.MINUS => left - right,
            Operator.MULTIPLY => left * right,
            Operator.DIVIDE => left / right,
            _    =>  0
        }

Ref. https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8

Правильный ответ уже дан, тем не менее, вот лучший способ (чем переключение):

private Dictionary<Operator, Func<int, int, double>> operators =
    new Dictionary<Operator, Func<int, int, double>>
    {
        { Operator.PLUS, ( a, b ) => a + b },
        { Operator.MINUS, ( a, b ) => a - b },
        { Operator.MULTIPLY, ( a, b ) => a * b },
        { Operator.DIVIDE ( a, b ) => (double)a / b },
    };

public double Calculate( int left, int right, Operator op )
{
    return operators.ContainsKey( op ) ? operators[ op ]( left, right ) : 0.0;
}

Просто не приводите к int

 switch(operator)
    {
       case Operator.Plus:
       //todo

Нет необходимости конвертировать. Вы можете применять условия к Enums внутри коммутатора. Вот так,

public enum Operator
{ 
    PLUS,
    MINUS,
    MULTIPLY,
    DIVIDE
}

public double Calculate(int left, int right, Operator op)
{
    switch (op)
    {
        case Operator.PLUS: return left + right; 
        case Operator.MINUS: return left - right; 
        case Operator.MULTIPLY: return left * right;
        case Operator.DIVIDE: return left / right;
        default: return 0.0; 
    }
}

Затем назовите это так:

Console.WriteLine("The sum of 5 and 5 is " + Calculate(5, 5, Operator.PLUS));

Вы не должны приводить к целому числу. А для деления вам нужно сначала разыграть влево, чтобы удвоить, если нет, то вы будете делать целочисленное деление.

public enum Operator
{
    PLUS, MINUS, MULTIPLY, DIVIDE
}

public double Calculate(int left, int right, Operator op)
{
    double sum = 0.0;

    switch(op)
    {
       case Operator.PLUS:
       sum = left + right;
       return sum;

       case Operator.MINUS:
       sum = left - right;
       return sum;

       case Operator.MULTIPLY:
       sum = left * right;
       return sum;

       case Operator.DIVIDE:
       sum = (double)left / right;
       return sum;

       default:
       return sum;
   }

   return sum;
}
 public enum Operator
    {
        PLUS, MINUS, MULTIPLY, DIVIDE
    }

    public class Calc
    {
        public void Calculate(int left, int right, Operator op)
        {

            switch (op)
            {
                case Operator.DIVIDE:
                    //Divide
                    break;
                case Operator.MINUS:
                    //Minus
                    break;
                case Operator.MULTIPLY:
                    //...
                    break;
                case Operator.PLUS:
                    //;;
                    break;
                default:
                    throw new InvalidOperationException("Couldn't process operation: " + op);
            }
        }
    }

Если вы не хотите использовать оператор return для каждого случая, попробуйте это:

Calculate(int left, int right, Operator op)
{
   int result = 0;
   switch(op)
   {
        case Operator.PLUS:
        {
            result = left + right;;  
        }
        break;
        ....
   }

   return result;
}

Все остальные ответы верны, но вам также нужно правильно вызывать ваш метод:

Calculate(5, 5, Operator.PLUS))

И так как вы используете int за left а также rightрезультат будет int также (3/2 will result in 1). вы могли бы бросить на double перед вычислением результата или измените ваши параметры, чтобы принять double

Две вещи. Во-первых, вам нужно указать ссылку на enum в своем тесте - вместо "PLUS" это должен быть "Operator.PLUS". Во-вторых, этот код был бы намного более читабельным, если бы вы использовали имена членов перечисления, а не их интегральные значения в операторе switch. Я обновил ваш код:

public enum Operator
{
    PLUS, MINUS, MULTIPLY, DIVIDE
}

public static double Calculate(int left, int right, Operator op)
{
    switch (op)
    {
        default:
        case Operator.PLUS:
            return left + right;

        case Operator.MINUS:
            return left - right;

        case Operator.MULTIPLY:
            return left * right;

        case Operator.DIVIDE:
            return left / right;
    }
}

Назовите это с:

Console.WriteLine("The sum of 5 and 5 is " + Calculate(5, 5, Operator.PLUS));

Ваш код в порядке. Если вы не знаете, как использовать функцию "Рассчитать", попробуйте

Calculate(5,5,(Operator)0); //this will add 5,5
Calculate(5,5,Operator.PLUS);// alternate

Перечисляемые значения по умолчанию начинаются с 0 и увеличиваются на единицу для следующих элементов, пока вы не назначите другие значения. Также вы можете сделать:

public enum Operator{PLUS=21,MINUS=345,MULTIPLY=98,DIVIDE=100};
Другие вопросы по тегам