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
Comments
-
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 about 11 yearsWell .. yes, kind of... :-D
-
Stephan Bauer about 11 years@J.Starkl Well that's a matter of opinion, I think :-)
-
J.Starkl about 11 years@StephanBauer: Yes, it is :-)
-
Kenneth K. about 11 yearsMore of an indent man, myself =) Strangely enough, that's the only thing I don't put braces on. Go figure!
-
Matthew Watson about 11 yearsIf 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 about 11 yearsI think this is an example of where using var to declare the variable would be appropriate!
-
JustAndrei about 11 yearsVar cannot be used outside the method body.
-
Chris Dunaway about 11 yearsOh yes, I missed that it was declared outside of the method.
-
Stephan Bauer about 11 years@MatthewWatson Great! Thanks for mentioning that point with variabloes for a single case - never thought of that :-)
-
Adassko over 10 yearsYou can use
using OperatorsDict = Dictionary<Operator, Func<int, int, double>>
and then useOperatorsDict
instead -
Rafe about 10 yearsC# 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 about 10 yearsYes, but if you use them everywhere -no pitfalls -consistent code -improved readability -simpler maintenence/extension -best practice (get used to them)
-
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 over 8 years1. 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 over 8 yearsA. 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 about 8 yearsI'd like to see one reliable piece of evidence that Dictionary look-up is faster than 'Switch with Enums.
-
IARI almost 8 yearsabout the readability - I find python and haskell code way easier to read than c# or java
-
Matthieu Charbonnier over 6 yearsNote that the brackets isn't related to the switch/case: You can add brackets anywhere you want to separate variables.
-
Nadav over 4 yearsSwitch case enables you to reuse the same code block for multiple cases. If you do - make sure to not use brackets.
-
tekHedd about 4 yearsI 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 about 4 yearsUnclear 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 about 4 yearsThis 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 about 3 yearsAny syntactic sugar which reduces the need for curly braces is good.
-
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 over 2 yearsPlease cast one of the divided values into a double, don't confuse newcomers and spread incorrect code.