C# how to use enum with switch

249,573

Solution 1

You don't need to convert it

switch(op)
{
     case Operator.PLUS:
     {
        // your code 
        // for plus operator
        break;
     }
     case Operator.MULTIPLY:
     {
        // your code 
        // for MULTIPLY operator
        break;
     }
     default: break;
}

By the way, use brackets

Solution 2

Since C# 8.0 introduced a new switch expression for enums you can do it even more elegant:

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

Solution 3

The correct answer is already given, nevertheless here is the better way (than switch):

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

Solution 4

You should not cast to integer. And for the division, you need to cast left to double first, if not you will be doing an integer divide.

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

Solution 5

simply don't cast to int

 switch(operator)
    {
       case Operator.Plus:
       //todo
Share:
249,573
yesman
Author by

yesman

(my about me is currently blank) click here to edit!

Updated on July 08, 2022

Comments

  • yesman
    yesman almost 2 years

    I can't figure out how to use switches in combination with an enum. Could you please tell me what I'm doing wrong, and how to fix it? I have to use an enum to make a basic calculator.

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

    The end result should be something like this:

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

    Could you guys please tell me how I'm messing up?

  • Stephan Bauer
    Stephan Bauer about 11 years
    Well .. yes, kind of... :-D
  • Stephan Bauer
    Stephan Bauer about 11 years
    @J.Starkl Well that's a matter of opinion, I think :-)
  • J.Starkl
    J.Starkl about 11 years
    @StephanBauer: Yes, it is :-)
  • Kenneth K.
    Kenneth K. about 11 years
    More of an indent man, myself =) Strangely enough, that's the only thing I don't put braces on. Go figure!
  • Matthew Watson
    Matthew Watson about 11 years
    If you ever introduce a new variable for use in a single case, you do of course need to use brackets. And at that point my OCD kicks in and I need to make all the cases look the same by adding brackets to them. (In all seriousness, I use brackets in switch statements because I use them for blocks everywhere else.)
  • Chris Dunaway
    Chris Dunaway about 11 years
    I think this is an example of where using var to declare the variable would be appropriate!
  • JustAndrei
    JustAndrei about 11 years
    Var cannot be used outside the method body.
  • Chris Dunaway
    Chris Dunaway about 11 years
    Oh yes, I missed that it was declared outside of the method.
  • Stephan Bauer
    Stephan Bauer about 11 years
    @MatthewWatson Great! Thanks for mentioning that point with variabloes for a single case - never thought of that :-)
  • Adassko
    Adassko over 10 years
    You can use using OperatorsDict = Dictionary<Operator, Func<int, int, double>> and then use OperatorsDict instead
  • Rafe
    Rafe about 10 years
    C# can have multi-line blocks without brackets since all must terminate with a return or break, goto or have no code at all. Fall-through is not allowed outside of these options: stackoverflow.com/questions/174155/…
  • J.Starkl
    J.Starkl about 10 years
    Yes, but if you use them everywhere -no pitfalls -consistent code -improved readability -simpler maintenence/extension -best practice (get used to them)
  • Stix
    Stix over 8 years
    @JustAndrei - (I know it is an old post) Why is this method better than switch - is it faster ? or is it preference ? I would like to know not for arguments sake but better coding - I have always used switch but never thought to use a dictionary function. Certainly should not be in a serializable object.. of course Adassko's comment kind of makes my thoughts on a memory issue go away.
  • JustAndrei
    JustAndrei over 8 years
    1. Separation of configuration and logic: your code becomes short and easy to read. Your configuration reads like a table, what is easy as well. 2. Unlike switch, Dictionary internally uses a hashtable for fast lookup, what becomes significant when there are many cases. Sometimes programmers put the most used item at the end of the switch and have problems with performance. 3. Once the configuration is extracted from the code, now you can make a lot of great things:
  • JustAndrei
    JustAndrei over 8 years
    A. Move it from the code to an external source, e.g. configuration file or database. B. Dynamically modify configuration upon your needs, right while program execution. C. Create a plugin system, so that your configuration is extended by modules. D. Although Dictionary already helps to search the key faster, you can make it even better by customizing the way you lookup the operation. Once I implemented such a replacement for the switch, which accumulated case usage statistics during program execution, and periodically re-arranged the list of cases so that the most popular one became the first.
  • BillW
    BillW about 8 years
    I'd like to see one reliable piece of evidence that Dictionary look-up is faster than 'Switch with Enums.
  • IARI
    IARI almost 8 years
    about the readability - I find python and haskell code way easier to read than c# or java
  • Matthieu Charbonnier
    Matthieu Charbonnier over 6 years
    Note that the brackets isn't related to the switch/case: You can add brackets anywhere you want to separate variables.
  • Nadav
    Nadav over 4 years
    Switch case enables you to reuse the same code block for multiple cases. If you do - make sure to not use brackets.
  • tekHedd
    tekHedd about 4 years
    I think it's a bit odd that you use braces for every case (so they'll match) but...not for "default:"...heck default is even on the same line, not matching the other cases. Not exactly criticizing, just enjoying how different people define "consistent" in different ways.
  • tekHedd
    tekHedd about 4 years
    Unclear how this makes the code more readable, other than to enforce project-local style conventions. OP's example block of code is a classic example of how early-return can make code more readable.
  • tekHedd
    tekHedd about 4 years
    This answer illustrates perfectly the right time to break the convention and use 1) early return from a function and 2) putting the case on the same line as the code.
  • 0b101010
    0b101010 about 3 years
    Any syntactic sugar which reduces the need for curly braces is good.
  • 0b101010
    0b101010 about 3 years
    @BillW You won't, because it isn't. Using a dictionary for this is a simply dreadful design choice.
  • Mindaugas Bernatavičius
    Mindaugas Bernatavičius over 2 years
    Please cast one of the divided values into a double, don't confuse newcomers and spread incorrect code.