Multiple Switch statements with multiple cases? - c#

I'm trying to write a switch statement that would have a similar effect to what I show in the code below, but (obviously), it's not working. It will be impossible to have something selected in both combo boxes at once. Any thoughts on how to accomplish this? I'm updating an older program, and I'm trying not to re-write a large chunk of the code.
switch ((cboMAIN.SelectedIndex) || (cboMAINalternate.SelectedIndex))
{
case 0:
OutputString1 = "A";
break;
case 1:
OutputString1 = "C";
break;
case 2:
OutputString1 = "E";
break;
case 3:
OutputString1 = "F";
break;
case 4:
OutputString1 = "I";
break;
case 5:
OutputString1 = "J";
break;
case 6:
OutputString1 = "K";
break;
}

Try using
switch ((cboMAIN.SelectedIndex > -1) ? cboMAIN.SelectedIndex : cboMAINalternate.SelectedIndex)
{

No, that's not possible (at least not the way you're doing it).
The question would be, what are you trying to achieve? If you'd have some kind of toggle to switch between both indexes, you could do something like that:
bool useAlternative = ...;
switch(useAlternative ? cboMAINalternate.SelectedIndex : cboMAIN.Selectedindex) {
// ...
}

There is always a selected item in a select element, so you have to check for the one that you consider to be no selecton, for example the first item:
var item = cboMAIN.SelectedIndex;
if (item = 0) item = cboMAINalternate.SelectedIndex;
switch (item) {
...

Probably the concisest way:
switch (Math.Max(cboMAIN.SelectedIndex, cboMAINalternate.SelectedIndex))
{
// ...
}

According to MSDN, SelectedIndex will return -1 if the selection is empty on a ComboBox.
The following code should choose a ComboBox with a selection and go through your switch statement, or fail if neither has a selection:
ComboBox comboBoxToUse;
if (cboMAIN.SelectedIndex > -1)
{
comboBoxToUse = cboMAIN;
}
else if (cboMAINalternate.SelectedIndex > -1)
{
comboBoxToUse = cboMAINalternate;
}
else
{
throw new InvalidOperationException("Neither combo box contains a selection.");
}
switch (comboBoxToUse.SelectedIndex)
{
...
}
You may also want to throw an exception if both ComboBoxes have a selection.

Related

C# Case which include other cases

How to execute in one case, other cases? I could just copy paste those other cases, or put it to some external function but there is so much code so I dont want to do that.
Example:
switch(foo)
{
case 3:
{
//something
}break;
case 4:
{
//something else
}break;
case 5:
{
//here i want to execute case 3 and case 4
}break;
}
I think that this was previously answered but I can't find how to do it.
C# doesn't have such functionality. You have to create other methods which will do actions for cases 3 and 4 and call them from case 5 branch. I would suggest to create a separate class FooHandler which would handle your value. It's easily extendable and readable.
public class FooHandler
{
private readonly int _foo;
public FooHandler(int foo)
{
this._foo = foo;
}
public void Handle()
{
switch(this._foo)
{
case 3: this.HandleCase3(); break;
case 4: this.HandleCase4(); break;
case 5: this.HandleCase5(); break;
default: throw new ArgumentException("Foo value is invalid");
}
}
private void HandleCase3()
{
// Your code for case 3
}
private void HandleCase4()
{
// Your code for case 4
}
private void HandleCase5()
{
this.HandleCase3();
this.HandleCase4();
}
}
Usage:
var fooHandler = new FooHandler(foo);
fooHandler.Handle();
If you don't want to add methods (you didn't explain why),
you can use Action local variables holding Lambda expressions.
In the example below you can replace the body of the lambdas with whatever code you have for "something" and "something else".
Action also supports passing arguments to the lambda's body if you need them.
Action something = () => { Console.WriteLine("something"); };
Action something_else = () => { Console.WriteLine("something_else"); };
switch (foo)
{
case 3:
something();
break;
case 4:
something_else();
break;
case 5:
something();
something_else();
break;
}
You could also change the switch to two ifs:
if (foo == 3 || foo == 5)
{
//something
}
if (foo == 4 || foo == 5)
{
//something else
}
It would be easier to use if-statements. Here I also used pattern matching to simplify the tests.
if (foo is 3 or 5) {
// something
}
if (foo is 4 or 5) {
// something else
}
So simple and easy to read and understand.
I would argue that the code being intuitive is important; hence, I would suggest defining helper variables that clarify intention.
While not knowing the meaning of 3, 4 and 5, a hypothetical example could be:
var awesomeFoos = new[] { 3, 5 };
var popularFoos = new[] { 4, 5 };
var fooIsAwesome = awesomeFoos.Contains(foo);
var fooIsPopular = popularFoos.Contains(foo);
if (fooIsAwesome)
{
// something (preferably refactored to a separate method)
}
if (fooIsPopular)
{
// something else (preferably refactored to a separate method)
}
, where .Contains() is found in the System.Linq namespace.
An example fiddle is found here.
That being said, though; you seem quite determined that you would prefer to keep your code as-is, to an as large extent as possible. If that is really a high priority, you could consider putting the whole foo-switch logic inside a method and let it call itself twice in the case 5 scenario:
private static void HandleFoo(int foo)
{
switch(foo)
{
case 3:
{
// something
}break;
case 4:
{
// something else
}break;
case 5:
{
HandleFoo(3);
HandleFoo(4);
}break;
}
}
Example fiddle is found here.
(Depending on the content of // something and // something else, this may not be feasible, though.)
I strongly recommend changing the way you want to implement this statement. This method is not suitable for modern applications and is coupled with everything. But if you need to implement as you asked, You can jump between cases by using goto.
For more information Read "jump statements".
int a = 10;
switch (a)
{
case 0:
//Condition1:
//some actions
break;
case 1:
goto case 0;
//or
goto Condition1;
break;
default:
break;
}
Since this is the linear approach you should check conditions in if for each goto in each case(cause you can't Go back to each step)
Another approach is to save all cases in the order you want to execute and run the switch multiple times. I use a while in my example you can use goto if you don't want to use a loop.
Queue<int> cases = new Queue<int>();
//1 is the main switch value
cases.Enqueue(1);
while (cases.Count > 0)
{
int temp = cases.Dequeue();
switch (temp)
{
case 0:
Console.WriteLine("0");
break;
case 1:
Console.WriteLine("1");
cases.Enqueue(3);//run case 3
cases.Enqueue(0);//then run case 0
break;
case 2:
Console.WriteLine("2");
break;
case 3:
Console.WriteLine("3");
break;
default:
break;
}
}

Trying to use switch statement insted of if else to find out which value is bigger or smaller

I am a beginner in learning c# (and any coding language)
I am trying to use switch statement instead of if else.
this is the working if else statement
private void RunScript(int a, int b, ref object A)
{
if (a < b)
{
Print("a is smaller than b");
Print("b is bigger than a");
}
else if (a > b)
{
Print("a is bigger than b");
Print("b is smaller than a");
}
else
{
Print("a equals b");
}
this is the switch that I am trying to do
private void RunScript(double a, double b, ref object A)
{
double whichIsBigger = a - b;
//below is the 58th line
switch (whichIsBigger)
{
case whichIsBigger < 0:
Print("a is bigger than b");
break;
case whichIsBigger > 0:
Print("a is smaller than b");
break;
default:
Print("a equals b");
break;
}
It gives me this
Error (CS0151): A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type (line 58)
FYI, I'm trying to do this on rhinoceros3d, using the rhino common library.
and also, I've been trying to find a website or forum to learn c# where I can
ask questions like these. I ended up here.
I think that this kind of questions is pretty basic, but I can't find a
resource that can give me an answer to this problem.
I have read several posts and can't find a similar problem
If there are any sites where people can answer my questions fast like a chat room or something,
please do let me know.
Basically, you're trying to run an evaluation in your case statement. You have to do the evaluation before, and use the values in your case statement.
If it's a true / false situation, you shouldn't use switch. Switch is generally for when there are a number of options that could be true. For example, if you had an enum with multiple values, and you want to do something different for each value (like DayOfWeek.Monday, DayOfWeek.Tuesday, etc). For the exact reason you're running into here.
If you really wanted, you could create an enum of ABCompare.Bigger, ABCompare.Smaller, ABCompare.Equal or something like that, and then switch on that -- but that doesn't really make sense.
The switch statement works by comparing the value you pass in to a list of alternatives you provide. So, you can do:
switch (a < b)
{
case true:
// do some stuff
break;
case false:
switch (a > b)
{
case true:
// do other stuff
break;
case false:
// do other other stuff
break;
}
break;
}
but you can't do direct comparisons in the case statement because they're already doing a comparison with the value you passed into the original switch.
Also, the afore-mentioned example is a poor use case for switch as it would be better-handled by an if-else. If your goal is to understand switch, my advice would be to try converting an enum to some other type based on its values:
public enum Color
{
Red,
Blue,
Green,
}
public string ConvertToHexWithIfElse(Color myColor)
{
if (myColor == Color.Red)
{
return "#FF0000";
}
else if (myColor == Color.Green)
{
return "#00FF00";
}
else if (myColor == Color.Blue)
{
return "#0000FF";
}
return string.Empty;
}
public string ConvertToHexWithSwitch(Color myColor)
{
switch (myColor)
{
case Color.Red:
return "#FF0000";
case Color.Blue:
return "#0000FF";
case Color.Green:
return "#00FF00";
default:
return string.Empty;
}
}
Note that even this example is somewhat of a poor use of switch because the enum was a forced contrivance used simply to show the usage. IMHO switch doesn't have many actual uses: you either use a dictionary or you use an if-else.
When doing a switch statement each "case" is not supposed to have a conditional in it. Switch statements are designed to "switch" values. Like for example, swapping colors!
Color c = (Color) (new Random()).Next(0, 3);
switch (c)
{
//Value of "c" is red
case Color.Red:
Console.WriteLine("Red!");
break;
//Value of "c" is green
case Color.Green:
Console.WriteLine("Green!");
break;
//Value of "c" is blue
case Color.Blue:
Console.WriteLine("Blue!");
break;
//"c" is not red, green, or blue, so we default our message to say the color is unknown!
default:
Console.WriteLine("The color is not known.");
break;
}
In each "case" we see if "c" is a specific value, and if not, we have a default in our switch statement to handle the scenario.

How can I use web.config value in switch case in C# without if , else loop "A constant value is expected."

Below is switch case
switch (strID)
{
case ConfigurationManager.AppSettings["Key1"].ToString():
Label1.Visible = true;
break;
case ConfigurationManager.AppSettings["Key2"].ToString():
Label2.Visible = true;
break;
case ConfigurationManager.AppSettings["Key3"].ToString():
Label3.Visible = true;
break;
default:
Label1.Visible = true;
break;
}
But it gives error "A constant value is expected."
I know that you can't have variables in the switch statement.But is any way ?
You can use only constant value in case statement.
Better you can use if statement e.g.
if(ConfigurationManager.AppSettings["Key1"].ToString() == strID)
{
Label1.Visible = true;
}
else if(ConfigurationManager.AppSettings["Key2"].ToString() == strID)
{
Label2.Visible = true;
}
.
.
.
.
.
.
.
else
{
//default
}
You can have variables in switch's CASE statements. But, that must be a compile time constants i.e. `const' variable.
CASE statements need to be constant; by having them be constant it allows the statement to be much more heavily optimised. Switch will generate the equivalent of a hash table with the case statement values as keys. That approach couldn't be used if the values can change.
Values from ConfigurationManager.AppSettings are decided at run-time. So you can not use it in Switch's CASE statements.
You can use if.. else statements as alternative solution.
See - C# switch statement limitations - why?
Assign the 3 values from Web.Config file to 3 different constants like const string key1 = ConfigurationManager.AppSettings["Key1"].ToString() and use them in the cases inside switch instead of giving ConfigurationManager.Appsettings["Key1"].ToString();

alternatives to switch-case

I want to know if this kind of switch-case usage is appropriate, or there is any other alternatives (patterns)?
the following is part of my program:
the basics is I am doing a sequence of actions
generally program control is following the sequence of case one by one;
usually any specific case is not finished in its first call, we have to wait until the procX returns true. (waiting for instrument response or action completion);
jump to a specific case is possible (changing StepCurrent in the sampling code).
I found this kind of switch-case is hard to maintain, especially by changing the StepCurrent to direct control flow. And code looks ugly.
is there any better method?
note: though I am using C#, the problem might not be limited to it.
while (true)
{
if (sig_IsExit())
{
break;
}
Thread.Sleep(500);
bRetSts = false;
switch (StepCurrent) // nSeq)
{
case 0:
bRetSts = proc0();
break;
case 1:
bRetSts = proc1();
break;
case 2:
bRetSts = proc2();
break;
case 3:
bRetSts = proc3();
break;
case 4:
...
}
if( bRetSts )
StepCurrent++;
}
You can use a Dictionary<int,Func<bool>> , with this you will have less cyclomatic complexity, see the example:
Note: i use Dictionary to show that you can use any type as key, for example a string with a name, or an enum.
Dictionary<int,Func<bool>> proc = new Dictionary<int,Func<bool>>
{
{0, proc0},
{1, proc1},
{2, proc2},
{3, proc3},
}
and than use like that:
while (true)
{
if (sig_IsExit())
break;
Thread.Sleep(500);
bRetSts = false;
bRetSts = proc[StepCurrent]();
if( bRetSts )
StepCurrent++;
}
bRetSts = (StepCurrent == 0)? proc0():
(StepCurrent == 1)? proc1():
(StepCurrent == 2)? proc2():
(StepCurrent == 3)? proc3():
false; // it could be more proper to throw an exception
or, perhaps more appropriate if all procX have the same signature:
var funcs = new Func<bool>[] { proc0, proc1, proc2, proc3 };
funcs[StepCurrent]();
I think this is perfect opportunity to use Chain of responsibility design pattern.
Here is one of the better descriptions I found: https://sourcemaking.com/design_patterns/chain_of_responsibility Also example of implementation: http://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm

Possible to use && or || in switch statement? Visual C#

So I was making a Rock Paper Scissor game and I've sort of made adjustments to it to include life and other things. Now I got stuck with the switch statement. My if statement works fine:
private void Result_TextChanged(object sender, EventArgs e)
{
if (playerscore == 1 || pcscore == 1)
{
PlayerLife.Image = Properties.Resources.Five;
}
}
I was wondering how I could translate this to the switch statement?
private void Result_TextChanged(object sender, EventArgs e)
{
switch (playerscore || pcscore)
{
case 1:
PlayerLife.Image = Properties.Resources.Five;
break;
}
}
Doesn't seem to work.
The simple answer is No. You cant use it like that.
Switch works with single expression.
You may check MSDN for details.
You may try like this:-
if (playerscore == pcscore)
{
switch (playerscore)
{
case 1:
PlayerLife.Image = Properties.Resources.Five;
break;
}
}
EDIT:-
As commented by Jeppe Stig Nielsen in the comments, You can switch on any expression of a suitable type. That expression may contain ||. There can be many case labels associated with each switch section in a switch block.
But personally speaking that would not be a good practice to follow. You may try to use if statement for that.
You may try like this if you want:
switch (playerscore == 1 || pcscore == 1)
In C#, a switch statement resolves a single expression and compares that value with a list of possible cases:
switch(someExpression)
{
case x: // This runs if someExpression == x
break;
case y: // This runs if someExpression == y
break;
}
Now, you could switch on the expression (playerscore == 1 || pcscore == 1) like so:
switch(playerscore == 1 || pcscore == 1) // This expression is either true or false
{
case true: // Runs if playerscore is 1 or pcscore is 1
break;
case false: // runs if neither playscore or pcscore are 1
break;
}
However, the above is rather unreadable and silly. You'd be best off with the if statement:
if(playerscore == 1 || pcscore == 1)
{
// Runs if playerscore is 1 or pcscore is 1
}
else
{
// runs if neither playscore or pcscore are 1
}
You could write it like this but why would you want to?
switch (playerscore == 1 || pcscore == 1)
{
case true:
PlayerLife.Image = Properties.Resources.Five;
break;
default:
break;
}
As Jeppe points out in the comment below, when you use || or && you end up with a bool and an if statement should be used.
Here is a great answer by #EricLippert on what can be used as the expression in a swtich statement.
What you are trying to do doesn't make sense, if playerscore = 3 and pcscore = 2 then what would playerscore || pcscore be equal to?
If you have a whole bunch of variables, say not just two, but 5, 10, or even an unknown number, then what you can do is put all of the values that you want to compare to 1 into a collection and then act on that collection as a whole.
//this could just be a list/array accepted as a paramter,
//can include other variables, or whatever
var scores = new []{playerscore, pcscore};
if(scores.Any(score => score == 1))
PlayerLife.Image = Properties.Resources.Five;
switch isn't really an appropriate tool for manipulating collections like this.
This makes no sense: in a switch statement you always want to compare with a specific type, rather than to a boolean value as follows:
switch (playerscore || pcscore)
in your case use the 'if'-statement
Suppose that playerscore and pcscore are integer who has 0 or 1 as possible values
resp = playerscore + 10 * pcscore;
switch (resp)
{
case 0:
// both are false
break;
case 1:
// playerscore true
break;
case 10:
// pcscore true
break;
case 11:
// both are true
break;
default:
// error in input data
break;
}

Categories

Resources