I have a code like this :
if(x==1 && y==2){
something...
}
else if(x==4 && y==6){
something...
}
else{
something...
}
Can I convert it to a switch case statement
You can't since switch is taking only one variable; and you have two variables.
You can always refactor your code a little bit though.
Like:
if (x==1 && y==2) {
//something...
return;
}
if (x==4 && y==6) {
//something...
return;
}
//something...
Much more readable (imho).
EDIT
This is crazy :) but since your variables are integer you can combine them into one long variable and use the switch.
Like:
switch ((((long)x) << 32) + y) {
case ((1L << 32) + 2):
break;
case ((4L << 32) + 6):
break;
default:
break;
}
Well.... if you have to this would work: WARNING - HACK CODE
int x;
int y;
var #switch= new Dictionary<Func<bool> statement, Action doIfTrue>
{
{() => x == 1 && y == 2, something},
{() => x == 4 && y == 6, somethingElse}
{() => true, () = {} } // fallback action
};
#switch.Where(pair => pair.Key()).Select(pair => pair.Value).First()();
This could probably be written a bit more terse.
It does depend a bit on how the bigger picture code looks, but I've used the following technique occasionally.
switch (x*100+y) {
case 102:
// something...
break;
case 406:
// something...
break;
default:
// something...
}
It's pretty readable, but can get out of hand.
Related
How do I jump to another case statement in a switch-case condition with the value of current case statement?
Is it possible to implement this kind of things using switch case or is there another way to implement it?
Is it possible to achieve? If not, then is there another way to achieve it?
This code works:
switch (this.Name)
{
case "":
if (this.Owner == null)
{
goto DoBill;
}
break;
case "Bill":
DoBill:
break;
}
However, anyone who actually does it should be shot. Or talked to very severely, at the least. Why not just do the sensible thing?
switch (param.Component.Type)
{
case "Combo":
returnComboItemSelect = generateCB(param);
if(returnComboItemSelect=="Slider")
{
returnSomething = generateSl(param,returnComboItemSelect); //I mean no need to jump
}
break;
case "List":
returnSomething = generateL(param);
break;
case "Slider":
returnSomething
.....
Seriously, if you start jumping about between case statements then you shouldn't be using them. I'm not too keen on the code above either (duplication, but sometimes...)
You could but a while loop around the switch statement and break out of the loop when you are done.
var keepLooping = true;
var switchCaseSwitch = param.Component.Type;
while(keepLooping)
{
switch (switchCaseSwitch)
{
case "Combo":
returnComboItemSelect = generateCB(param);
if (returnComboItemSelect == "Slider")
{
switchCaseSwitch = "Slider";
}
else
{
keepLooping = false;
}
break;
case "List":
returnSomething = generateL(param);
keepLooping = false;
break;
case "Slider":
returnSomething = generateSl(param,1);
keepLooping = false;
break;
case "RadioButtons":
returnSomething = generateRB(param);
keepLooping = false;
break;
case "CheckBox":
returnSomething = generateCHB(param,flag);
keepLooping = false;
break;
default:
throw new Exception("Unknown component type");
}
}
Or you could ditch the case statement and do something like that:
//Setup
var selector = new Dictionary<string, Func<Param, string, string>>();
selector.Add("Combo", (p, flag) =>
{
var returnComboItemSelect = generateCB(p);
if (returnComboItemSelect == "Slider")
{
return selector["Slider"](p, returnComboItemSelect);
}
return returnComboItemSelect;
});
selector.Add("List", (p, flag) => { return generateL(p); });
selector.Add("Slider", (p, flag) => { return generateSL(p, flag); });
selector.Add("RadioButtons", (p, flag) => { return generateRB(p); });
selector.Add("CheckBox", (p, flag) => { return generateCHB(p, flag); });
//use
var result = selector[param.Component.Type](param, flag);
I think you would be FAR better off rethinking your architecture.
People dont tend to use GOTO in C# these days unless they are trying to break nested loops.
for example
foreach(var item in items){
foreach(var name in item.people){
if(name == WhatIAmSearchingFor)
goto found;
}
}
found:
//Your Code
MSDN Reference on GOTO
Something as simple as returning a Func, and a property bag of params is a clearer way to do this. Or like I have in the example below just do your first param and then an enum or flag of some sort. Instead of passing an empty one just make it 0
Here is a S.O. answer on how to do this Can a C# method return a method?
So in your example you might do this
public Func<ParamType,int> YourMethodName{
YourSwitch{
case(1)
return YourClassName.YourMethod;
break;
case(2)
return YourClassName.YourMethod2;
break
case(3)
return YourClassName.YourMethod3;
break
}
}
You can use a goto case.
A common use case is when you want one case to run to the next case.
switch ( arg )
{
case "-file":
if ( (i + 1) < args.Length && !args[i + 1].StartsWith("-") )
inputBox.Text = args[++i];
break;
case "-language":
_loadSelectedLanguagesAsALanguageSet = true;
goto case "-select";
case "-select":
if ( (i + 1) < args.Length && !args[i + 1].StartsWith("-") )
_loadSelectedLanguageFileOnStartup = args[++i];
break;
}
could I turn this into a switch statement ?
if (donation_euro.Text.Trim().Equals(""))
{
donation_euro.Text = "00.00";
}
if (donation_lui.Text.Trim().Equals(""))
{
donation_lui.Text = "00.00";
}
if (donation.Text.Trim().Equals(""))
{
donation.Text = "00.00";
}
No, because your are not switching on a single variable, but multiple.
I suspect your motivation to do this, is to make the code more readable ? If this is the case, you could put the common logic of your three if's into a method, to reuse the code and better convey the intent.
Not Possible.as switch takes Expression and executes the matching Constant Case Label.
From MSDN :Switch-Case
Each case label specifies a constant value. The switch statement
transfers control to
the switch section whose case label matches
the value of the switch expression
Switch(Expression)
{
case constant1://statements
break;
case constant2://statements
break;
case constant3://statements
break;
}
if you want to switch with single value then it is possible
int a = 3;
if (a == 1)
{
//statements
}
else if(a == 2)
{
//statements
}
else if(a == 3)
{
//statements
}
else if(a == 4)
{
//statements
}
else
{
//statements
}
can be converted into switch as below:
int a = 3;
switch(a)
{
case 1: //statements
break;
case 2: //statements
break;
case 3: //statements
break;
case 4: //statements
break;
default : //statements
break;
}
This question already has answers here:
Multiple cases in switch statement
(24 answers)
Closed 1 year ago.
I want to use switch, but I have many cases, is there any shortcut? So far the only solution I know and tried is:
switch (number)
{
case 1: something; break;
case 2: other thing; break;
...
case 9: .........; break;
}
What I hope I'm able to do is something like:
switch (number)
{
case (1 to 4): do the same for all of them; break;
case (5 to 9): again, same thing for these numbers; break;
}
Original Answer for C# 7
A bit late to the game for this question, but in recent changes introduced in C# 7 (Available by default in Visual Studio 2017/.NET Framework 4.6.2), range-based switching is now possible with the switch statement.
Example:
int i = 63;
switch (i)
{
case int n when (n >= 100):
Console.WriteLine($"I am 100 or above: {n}");
break;
case int n when (n < 100 && n >= 50 ):
Console.WriteLine($"I am between 99 and 50: {n}");
break;
case int n when (n < 50):
Console.WriteLine($"I am less than 50: {n}");
break;
}
Notes:
The parentheses ( and ) are not required in the when condition, but are used in this example to highlight the comparison(s).
var may also be used in lieu of int. For example: case var n when n >= 100:.
Updated examples for C# 9
switch(myValue)
{
case <= 0:
Console.WriteLine("Less than or equal to 0");
break;
case > 0 and <= 10:
Console.WriteLine("More than 0 but less than or equal to 10");
break;
default:
Console.WriteLine("More than 10");
break;
}
or
var message = myValue switch
{
<= 0 => "Less than or equal to 0",
> 0 and <= 10 => "More than 0 but less than or equal to 10",
_ => "More than 10"
};
Console.WriteLine(message);
Here is a better and elegant solution for your problem statement.
int mynumbercheck = 1000;
// Your number to be checked
var myswitch = new Dictionary <Func<int,bool>, Action>
{
{ x => x < 10 , () => //Do this!... },
{ x => x < 100 , () => //Do this!... },
{ x => x < 1000 , () => //Do this!... },
{ x => x < 10000 , () => //Do this!... } ,
{ x => x < 100000 , () => //Do this!... },
{ x => x < 1000000 , () => //Do this!... }
};
Now to call our conditional switch
myswitch.First(sw => sw.Key(mynumbercheck)).Value();
Alternate for Switch/ifElse
To complete the thread, here is the syntax with C# 8 and C# 9 :
C# 9 syntax:
var percent = price switch
{
>= 1000000 => 7f,
>= 900000 => 7.1f,
>= 800000 => 7.2f,
_ => 0f // default value
};
If you want to specify the ranges :
var percent = price switch
{
>= 1000000 => 7f,
< 1000000 and >= 900000 => 7.1f,
< 900000 and >= 800000 => 7.2f,
_ => 0f // default value
};
C# 8 syntax:
var percent = price switch
{
var n when n >= 1000000 => 7f,
var n when n >= 900000 => 7.1f,
var n when n >= 800000 => 7.2f,
_ => 0f // default value
};
If you want to specify the ranges :
var percent = price switch
{
var n when n >= 1000000 => 7f,
var n when n < 1000000 && n >= 900000 => 7.1f,
var n when n < 900000 && n >= 800000 => 7.2f,
_ => 0f // default value
};
I would use ternary operators to categorize your switch conditions.
So...
switch( number > 9 ? "High" :
number > 5 ? "Mid" :
number > 1 ? "Low" : "Floor")
{
case "High":
do the thing;
break;
case "Mid":
do the other thing;
break;
case "Low":
do something else;
break;
case "Floor":
do whatever;
break;
}
If-else should be used in that case, But if there is still a need of switch for any reason, you can do as below, first cases without break will propagate till first break is encountered. As previous answers have suggested I recommend if-else over switch.
switch (number){
case 1:
case 2:
case 3:
case 4: //do something;
break;
case 5:
case 6:
case 7:
case 8:
case 9: //Do some other-thing;
break;
}
You could have switch construct "handle" ranges by using it in conjunction with a List of your bounds.
List<int> bounds = new List<int>() {int.MinValue, 0, 4, 9, 17, 20, int.MaxValue };
switch (bounds.IndexOf(bounds.Last(x => x < j)))
{
case 0: // <=0
break;
case 1: // >= 1 and <=4
break;
case 2: // >= 5 and <=9
break;
case 3: // >= 10 and <=17
break;
case 4: // >= 18 and <=20
break;
case 5: // >20
break;
}
With this approach ranges can have different spans.
Interval is constant:
int range = 5
int newNumber = number / range;
switch (newNumber)
{
case (0): //number 0 to 4
break;
case (1): //number 5 to 9
break;
case (2): //number 10 to 14
break;
default: break;
}
Otherwise:
if else
As mentioned if-else would be better in this case, where you will be handling a range:
if(number >= 1 && number <= 4)
{
//do something;
}
else if(number >= 5 && number <= 9)
{
//do something else;
}
In .Net only Visual Basic allows ranges in switch statements, but in C# there is no valid syntax for this.
Tackling your specific problem in C#, I would solve it thus:
if(number >= 1 && number <= 9) // Guard statement
{
if(number < 5)
{
// Case (1 to 4):
//break;
}
else
{
// Case (5 to 9):
//break;
}
}
else
{
// Default code goes here
//break;
}
To illustrate this further, imagine you have a percentage value.
Using your problem as a template, you might wish this to look like:
switch (percentage)
{
case (0 to 19):
break;
case (20 to 39):
break;
case (40 to 69):
break;
case (70 to 79):
break;
case (80 to 100):
break;
default:
break;
}
However, since C# doesn't allow that syntax, here is a solution that C# does allow:
if (percentage >= 0 && percentage <= 100) // Guard statement
{
if (percentage >= 40)
{
if (percentage >= 80)
{
// Case (80% to 100%)
//break;
}
else
{
if (percentage >= 70)
{
// Case (70% to 79%)
//break;
}
else
{
// Case (40% to 69%)
//break;
}
}
}
else
{
if (percentage >= 20)
{
// Case (20% to 39%)
//break;
}
else
{
// Case (0% to 19%)
//break;
}
}
}
else
{
// Default code goes here
//break;
}
It can take a little getting used to, but it's fine once you get it.
Personally, I would welcome switch statements to allow ranges.
The future of C# switch statements
Here are some ideas I had of how switch statements could be improved:
Version A
switch(value)
{
case (x => x >= 1 && x <= 4):
break;
case (x => x >= 5 && x <= 9):
break;
default:
break;
}
Version B
switch(param1, param2, ...)
{
case (param1 >= 1 && param1 <= 4):
break;
case (param1 >= 5 && param1 <= 9 || param2 != param1):
break;
default:
break;
}
If you use C/C++, there's no "range" syntax. You can only list all values after each "case" segment.
Language Ada or Pascal support range syntax.
If the range is small you can fall through cases to get to the same point. For example:
int number = 3;
switch (number)
{
case 1:
case 2:
case 3:
case 4:
Console.WriteLine("Number is <= 1 <= 4");
break;
case 5:
Console.WriteLine("Number is 5");
break;
default:
Console.WriteLine("Number is anything else");
break;
}
First of all, you should specify the programming language you're referring to.
Second, switch statements are properly used for closed sets of options regarding the switched variable, e.g. enumerations or predefined strings. For this case, I would suggest using the good old if-else structure.
If the question was about C (you didn't say), then the answer is no, but: GCC and Clang (maybe others) support a range syntax, but it's not valid ISO C:
switch (number) {
case 1 ... 4:
// Do something.
break;
case 5 ... 9:
// Do something else.
break;
}
Be sure to have a space before and after the ... or else you'll get a syntax error.
Through switch case it's impossible.You can go with nested if statements.
if(number>=1 && number<=4){
//Do something
}else if(number>=5 && number<=9){
//Do something
}
In C# switch cases are basically dictionaries on what to do next. Since you can't look up a range in a dictionary, the best you can do is the case ... when statement Steve Gomez mentioned.
You can use if-else statements with || operators (or-operator) like:
if(case1 == true || case2 == true || case3 == true)
{
Do this!...
}
else if(case4 == true || case5 == true || case6 == true)
{
Do this!...
}
else if(case7 == true || case8 == true || case9 == true)
{
Do this!...
}
Is it possible to add a additional Condition to Switch Statement like below in C#
switch(MyEnum)
{
case 1:
case 2:
case 3 && Year > 2012://Additional Condtion Here
//Do Something here..........
break;
case 4:
case 5:
//Do Something here..........
break;
}
In above mentioned example if MyEnum = 3 then it has to be excuted if Year > 2012... Is it possible?
[EDITED]
Year > 2012 is not applicable to case 1 & case 2.
C#7 new feature:
case...when
https://learn.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7
public static int DiceSum4(IEnumerable<object> values)
{
var sum = 0;
foreach (var item in values)
{
switch (item)
{
case 0:
break;
case int val:
sum += val;
break;
case IEnumerable<object> subList when subList.Any():
sum += DiceSum4(subList);
break;
case IEnumerable<object> subList:
break;
case null:
break;
default:
throw new InvalidOperationException("unknown item type");
}
}
return sum;
}
In order for it to work the way you've indicated with the fallthrough logic for 1 and 2, I'd suggest moving the //do something here portion out to a method or function and then doing this:
case 1:
case 2:
DoSomething();
break;
case 3:
if(Year > 2012) { DoSomething(); }
break;
The other alternative would be:
case 1:
case 2:
case 3:
if (MyEnum != 3 || Year > 2012) {
// Do something here
}
break;
but I think the first option is much more intuitive and readable.
The answer is no.
You'll need the following:
switch (MyEnum)
{
case 1:
case 2:
DoSomething();
break;
case 3:
if (Year > 2012) DoSomething();
break;
}
You can't add condition to a case. Case clause has to be a compile time constant. Instead you can use an if statement inside the case statement.
case 3:
if( > 2012)
{
//Do Something here..........
}
break;
You have to use the if condition inside your case , you can't use && in case statement, use like below:
switch(MyEnum)
{
case 1:
case 2:
case 3: //Additional Condtion Here
if (Year > 2012)
{
//Do Something here..........
}
break;
case 4:
case 5:
//Do Something here..........
break;
}
Or, alternatively, you can add the condition to the switch:
switch (MyEnum!=3 || Year>2012 ? MyEnum : -1)
{
case 1:
case 2:
case 3:
//Do Something here..........
break;
case 4:
case 5:
//Do Something here..........
break;
}
Most of the time, I do something like that...
(sorry for the naming, the use case didn't inspire me)
Considering those private classes:
private class NumberState
{
public static NumberState GetState(int number, int year)
{
if (number == 1)
return new FirstNumberState();
if (number == 2)
return new FirstNumberState();
if (number == 3 && year > 2012)
return new FirstNumberState();
if (number == 4)
return new SecondNumberState();
if (number == 5)
return new SecondNumberState();
return new DefaultNumberState();
}
}
private class FirstNumberState : NumberState { }
private class SecondNumberState : NumberState { }
private class DefaultNumberState : NumberState { }
Then you can do:
switch (NumberState.GetState(MyEnum, Year))
{
case FirstNumberState _:
// do something
break;
case SecondNumberState _:
// do something
break;
case DefaultNumberState _:
default:
throw new Exception("Unhandled number state");
}
It's easy to read even when your conditions get more complicated.
You can use C# 8 feature
public static bool SomeHelper(int value)
=> value switch
{
100 => true,
var x when x >= 200 && x <= 300 => true,
_ => false, // All other values
};
You will have true with values 100, 200...300 and false with other values
Also you can use params:
public static bool SomeHelper(int value, bool param)
=> value switch
{
100 => true,
var x when x >= 200 && x <= 300 && param => true,
_ => false, // All other values
};
in this case you will have true only if value is 100 and param is false
Can I use a for loop inside a switch/case?
Example code:
String[,] drinks = new String[,] { { "Cola", "20" }, { "Fanta", "20" }, { "Sprite", "20" }, { "Tuborg", "25" }, { "Carlsberg", "25" } };
switch (menuChoice)
{
case 0:
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
break;
for (int i = 0; i < drinksCount; i++)
{
case i+1:
buyDrink(drinks[i,0];
break;
}
(More code and methods is in between these)
Basically, I create an array with the drinks this machine sells, and then I want to create a menu where to chose these drinks, but also the ability to add more drinks within the GUI.
Is this even possible?
You can use loops inside switch statement but not the way you are using it currently. Try to replace your code with below code:
if (menuChoice == 0)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else if (menuChoice > 0 && menuChoice < drinksCount)
{
buyDrink(drinks[menuChoice, 0]);
}
ADDED:
As per valuable comments, why don't you just use -1 as menuChoice for Exit, this way:
if (menuChoice == -1)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else if (menuChoice > 0 && menuChoice <= drinksCount)
{
buyDrink(drinks[menuChoice - 1, 0], Convert.ToDouble(drinks[menuChoice - 1, 1]));
}
This way you can call your static method as shown:
static void buyDrink(String drink, double drinkPrice)
A better title for this question might be: Is it possible to have variable case statements?
case i+1:
This is an invalid case statement. A the value of a case statement must be a constant. If i were a constant in this case, it would be allowed. However, i isn't, and therefore the case statement will not compile.
Having said that, although the answer to the title question is yes, as shown by other answers, the real answer here is: Not the way you're trying to do it.
It doesn't make sense to have code after break.
You break from the case how do you expect it to execute?
case 0:
{
break;//If you break here, it exits the block.. your loop never executes
for (int i = 0; i < drinksCount; i++)
{
case i+1:
buyDrink(drinks[i,0];
break;
}
}
And even if it is possible I fail to see the point.
You will execute the case as long as it is greater than 0 right?
So why not just use an if statement, help yourself and others?
if(menuChoice ==0)
{
//dosomething
}
else if(menuChoice >0)
{
//buy drink
}
if(menuChoice == 0) {
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
} else if(menuChoice > 0 && menuChoice <= drinksCount) {
buyDrink(drinks[menuChoice - 1, 0]);
}
That code could not work at all.
A break is the final (and required) statement of a case.
Looking at your example you could simply write
if(menuChoice == 0)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else
{
buyDrink(drinks[menuChoice-1,0]);
}
EDIT: Seeing your comment about buyDrink as static method and the parameters required then you should change the call to buyDrink prepending the class name where the buyDrink method is defined and add the parameter for the price (as double value)
.......
else
{
BeverageClass.buyDrink(drinks[menuChoice-1,0], Convert.ToDouble(drinks[menuChoice-1,1]));
}