Add a additional condition to Case Statement in Switch - c#

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

Related

Trying to make a switch in a iqueryable any

I have five columns Cc1, Cc2, Cc3...
And I have the following switch statement in the "Any" to check in the columns based on the ccLevel, but the test1 table has 32 million rows and it takes forever to get them, is there a better way to make it faster?
if (_db.Test1.Any(x => CCLevels(x, ccLevel) == cCValue.CcCode))
{
some Message...
}
if (_db.Test2.Any(x => CCLevels(x, ccLevel) == cCValue.CcCode))
{
some Message...
}
private string CCLevels<T>(T x, string ccLevel) where T : IccLevels
{
string level = null;
switch (ccLevel)
{
case "1":
level = x.Cc1;
break;
case "2":
level = x.Cc2;
break;
case "3":
level = x.Cc3;
break;
case "4":
level = x.Cc4;
break;
case "5":
level = x.Cc5;
break;
}
return level;
}
When I make it like the following it takes a second,
if (_db.Test1.Any(x => x.Cc1 == cCValue.CcCode))
{
some Message...
}
if (_db.Test1.Any(x => x.Cc2 == cCValue.CcCode))
{
some Message...
}

C# Switch statement scenario

UPDATED:
Is there a way to accomplish what the code below attempts to do (doesn't pass syntax because case 2 and case 3 can't have duplicate declarations and/or because num can't be 2 and 3 at the same time)?
var num = 0;
switch (num)
{
case 1:
//do stuff applicable to 1 only;
break;
case 2:
//do stuff applicable to 2 only;
break;
case 3:
//do stuff applicable to 3 only;
break;
case 2:
case 3:
//do stuff applicable to 2 and 3 only;
break;
}
The question is confusingly posed. I think what you want is to have a case that runs for two, a case that runs for three, and a case that runs for two-or-three.
Just use two switches:
switch (num)
{
case 1: One(); break;
case 2: Two(); break;
case 3: Three(); break;
}
switch (num)
{
case 2:
case 3: TwoOrThree(); break;
}
Or
switch (num)
{
case 1: One(); break;
case 2:
case 3:
switch (num)
{
case 2: Two(); break;
case 3: Three(); break;
}
TwoOrThree();
break;
}
Or duplicate the code:
switch (num)
{
case 1: One(); break;
case 2: Two(); TwoOrThree(); break;
case 3: Three(); TwoOrThree(); break;
}
I would NOT recommend un-duplicating the code like this:
switch (num)
{
case 1: One(); break;
case 2: Two(); goto twoOrThree; break;
case 3: Three(); twoOrThree: TwoOrThree(); break;
}
Yuck.
not with a single-level switch (or a nasty GOTO). A switch can only execute one case. A better solution would be a nested if (or switch) within the 2/3 case:
switch (num)
{
case 1:
//do stuff applicable to 1 only
break;
case 2:
case 3:
if(num == 2)
{
//do stuff applicable to 2 only
}
if(num == 3)
{
//do stuff applicable to 3 only
}
//do stuff applicable to 2 OR 3
break;
}
It's as simple as this...
switch (value)
{
case 1:
// Do 1 stuff
break;
case 2:
case 3:
// We can use an if-else construct here given that there's only two possibilities.
if (value == 2)
{
// 2 only stuff here
}
else
{
// 3 only stuff here
}
// Do anything applicable to BOTH here, or above the if construct, depending on your requirements.
break;
default:
// Any other stuff here
break;
}
Or just use an if construct, which is arguably cleaner (switch is really only intended for simple many to one logical mappings)...
if (value == 1)
{
// 1 stuff
}
else if (value == 2 || value == 3)
{
if (value == 2) {
// 2 stuff only
}
else
{
// 3 stuff only
}
// 2 or 3 stuff, or above the if construct above, if you require.
}
else
{
// Anything else here
}
Or simply...
switch (value)
{
case 1:
OneStuff();
break;
case 2:
TwoStuff();
TwoOrThreeStuff();
break;
case 3:
ThreeStuff();
TwoOrThreeStuff();
break;
default:
AnythingElse();
}
And wrap what you need to do for each of the above in separate methods.
The third method would be my preference here. It's cleaner and easier to debug than using complex mixtures of switch and if.
You could just use if statements instead
var num = 0;
if(num == 1)
{
// do stuff applicable to 1 only
}
else if(num == 2)
{
// do stuff applicable to 2 only
}
else if(num == 3)
{
// do stuff applicable to 3 only
}
if(num == 2 || num == 3)
{
// do stuff applicable to 2 AND 3
}
Or as a switch and an if
switch (num)
{
case 1:
// do stuff applicable to 1 only
break;
case 2:
// do stuff applicable to 2 only
break;
case 3:
// do stuff applicable to 3 only
break;
}
if(num == 2 || num == 3)
{
// do stuff applicable to 2 AND 3
}
You could use the goto case statement and have a unique identifier for combined operations in case 2 and 3. Make sure that that is never hit by any other number:
var num = 0;
var text = "";
switch (num)
{
case 1:
text = "do stuff applicable to 1 only";
break;
case 2:
text = "do stuff applicable to 2 only";
goto case 23;
case 3:
text = "do stuff applicable to 3 only";
goto case 23;
case 23:
text = "do stuff applicable to 2 AND 3";
break;
}
The use of goto is not recommended in general but it is common to use it in switch-statements and situations like that.

How to jump to another case statement in a switch-case condition with the value of current case statement using C#

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

Turn if in to switch statement

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

How add "or" in switch statements?

This is what I want to do:
switch(myvar)
{
case: 2 or 5:
...
break;
case: 7 or 12:
...
break;
...
}
I tried with "case: 2 || 5" ,but it didn't work.
The purpose is to not write same code for different values.
By stacking each switch case, you achieve the OR condition.
switch(myvar)
{
case 2:
case 5:
...
break;
case 7:
case 12:
...
break;
...
}
You do it by stacking case labels:
switch(myvar)
{
case 2:
case 5:
...
break;
case 7:
case 12:
...
break;
...
}
You may do this as of C# 9.0:
switch(myvar)
{
case 2 or 5:
// ...
break;
case 7 or 12:
// ...
break;
// ...
}
case 2:
case 5:
do something
break;
Case-statements automatically fall through if you don't specify otherwise (by writing break). Therefor you can write
switch(myvar)
{
case 2:
case 5:
{
//your code
break;
}
// etc...
}
The example for switch statement shows that you can't stack non-empty cases, but should use gotos:
// statements_switch.cs
using System;
class SwitchTest
{
public static void Main()
{
Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large");
Console.Write("Please enter your selection: ");
string s = Console.ReadLine();
int n = int.Parse(s);
int cost = 0;
switch(n)
{
case 1:
cost += 25;
break;
case 2:
cost += 25;
goto case 1;
case 3:
cost += 50;
goto case 1;
default:
Console.WriteLine("Invalid selection. Please select 1, 2, or3.");
break;
}
if (cost != 0)
Console.WriteLine("Please insert {0} cents.", cost);
Console.WriteLine("Thank you for your business.");
}
}
Since C# 8 there are switch expressions that are better readable: no case, : and break;/return needed anymore. Combined with C# 9's logical patterns:
static string GetCalendarSeason(DateTime date) => date.Month switch
{
3 or 4 or 5 => "spring",
6 or 7 or 8 => "summer",
9 or 10 or 11 => "autumn",
12 or 1 or 2 => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Limitation: with this syntax, at the right of the => you cannot use curly braces ({ and }) for statements.

Categories

Resources