Using the switch statement instead of if - c#

so I just started programming and I started with c#. In the book I'm reading (learning c# 3.0), one of the exercises was this.
Exercise 5-2. Create a program that prompts a user for input, accepts an integer, then
evaluates whether that input is zero, odd or even, a multiple of 10, or too large (more
than 100) by using multiple levels of if statements.
I managed to to this but the next exercise was
Exercise 5-3. Rewrite the program from Exercise 5-2 to do the same
work with a switch statement.
I understand how switch statements work, but, I'm not sure how to work out if the user input number is odd/even, multiple of 10 and so on, and not use an if statement. Thank you for any help.

You can do this:
int input = ...
switch (input)
{
case 0:
Console.WriteLine("Zero");
default;
default:
switch (input < 100)
{
case true:
switch (Math.Abs(input) % 10)
{
case 0:
Console.WriteLine("Multiple of 10");
break;
case 2:
case 4:
case 6:
case 8:
Console.WriteLine("Even");
break;
default:
Console.WriteLine("Odd");
break;
}
break;
default:
Console.WriteLine("Too large");
break;
}
break;
}
I don't think you can do this with a single switch in C#—unless you make it so massive as to account from every number from 0-100. You might be able to do it with a single Select statement in VB.NET, which is similar to a C# switch but has significantly different semantics.

Related

C# switch comparison

I'm trying to learn programming C# (self taught) and I came to a point where I don't know if switch case can be used like if condition.
Can I make a comparison with switch like this?
switch(var)
{
case var < 10:
//Do something
break;
}
Or this is a case of why if condition is different compared to switch?
Certain comparisons can be done in switch cases via patterns. In your specific scenario, a relational pattern could check if a switch input is < 10.
switch(var)
{
case < 10:
//Do something
break;
}
One significant limitation of patterns is that the values inside them have to be constant. So if you had a variable int x and tried to use it in case < x: it wouldn't work.
https://dotnetcoretutorials.com/2020/08/10/relational-pattern-matching-in-c-9/
Deciding if to use an IF statement or SWITCH statement depends on a number of factors, including the readability of your code. There are times when multiple IF statements provide a more simpler approach than using switch. Other times it would be best to use a switch statement.
The simple answer to your question is yes but it would be best for you to try both in a particular scenario if you want to learn.
For most purposes switch is an alternative way to write an chain of if/else statement
switch(myVar)
{
case 1:
//Do something
break;
case 2:
//Do something
break;
case 3:
//Do something
break;
default:
//Do something else
}
Is equivalent to
if(myVar == 1) {
//Do something
}
else if(myVar == 2) {
//Do something
}
else if(myVar == 3) {
//Do something
}
else {
//Do something
}
In older versions of C# (pre 7.0) case statements were restricted to only testing if values were equal to a constant. However with the introduction of a feature called 'pattern matching' you can do more expressive matches within case statements. Subsequent C# versions have added more and more syntax in this area, but ultimately they don't do anything beyond what can be achieved with an if/else chain. For situations where there are a lot of conditions the switch/case statements are typically easier to read
An example of changes in syntax being allowed C# 9.0
switch(myVar)
{
case == 1:
//Do something
break;
case > 1 and < 3:
//Do something
break;
case == 3:
//Do something
break;
default:
//Do something else
}

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.

Is it possible to use the .ToUpper() method in C# on a string value that isn't stored in a variable?

I have a program that reads in parameters from a file. The file is read in one line at a time, and each line is checked to see if it holds a specific value or a blank. If line isn't blank space, the value in the line is passed to a switch statement. Here is a part of the swtich statement in question:
switch(stName)
{
//GENERAL section
case "JOBNAME":
_JobName = stValue;
break;
case "RUN AS-OF DATE":
_RunDate = stValue;
break;
case "USER NOTIFICATION EMAIL ADDRESS":
_UserEmailAddr = stValue;
break;
default:
System.Exception ex = new System.Exception("Unexpected parameter");
ex.Data.Add("Config File", oCommandArgs.ConfigFile);
ex.Data.Add("Parm Line", stIniLine);
ex.Data.Add("Delimiter", cDelimiter);
ex.Data.Add("Name", stName);
ex.Data.Add("Value", stValue);
throw ex;
}
The value in stName is converted to upper case prior to going to the switch statement. My question is, is it possible to use the .ToUpper() method on a string value that isn't stored in a variable? Basically, so that the code would resemble something like this:
switch(stName)
{
//GENERAL section
case "Jobname".ToUpper():
_JobName = stValue;
break;
case "Run as-of date".ToUpper():
_RunDate = stValue;
break;
case "User notification e-mail address".ToUpper():
_UserEmailAddr = stValue;
break;
default:
System.Exception ex = new System.Exception("Unexpected parameter");
ex.Data.Add("Config File", oCommandArgs.ConfigFile);
ex.Data.Add("Parm Line", stIniLine);
ex.Data.Add("Delimiter", cDelimiter);
ex.Data.Add("Name", stName);
ex.Data.Add("Value", stValue);
throw ex;
}
This is just to help simplify adding additional parameters.
In a switch statement, the case labels must be compile time constants; the compiler must know the result of the expression at compile time. The result of ToUpper() can not be, in C#, a compile time constant, code has to run in order to know the result, and therefore can't be used as you intend to.
const int one = 1;
const char c = 'c';
case 'c':
case c:
case 1:
case one:
case one + 1:
case default(int):
Are all valid.
int two = 2;
char a = 'a';
case two: //two is a variable
case a: //a is a variable
case 'c'.ToUpper(); //result of ToUpper is not known at compile time
case one.CompareTo(one): //result of CompareTo is not known at compile time
Are not.
Most practical solution? Decide on a casing criteria for your labels, write them all uppercase, or lower case, just be consistent, and then simply format accordingly the variable you are switching on:
switch(stName.ToUpper()) //<<<normalize casing here
{
case "JOBNAME":
_JobName = stValue;
break;
case "RUN AS-OF DATE":
_RunDate = stValue;
break;
...
}
If you have have to deal with localized upper and lower casing then use ToUpperInvariant or ToLowerInvariant. If that is not an option then switch is probably not the right tool for the job and you'll want to solve this with regular if-elseif-else statements.
Yes it is 100% possible and valid to do that on a string. You have access to all string methods doing it that way. However, switch statements require a constant value so you would not be able to do that in a switch. I would take a look at your code again and see why you would need it. Why not just write the value in all caps?
EDIT: Switch statements require a constant value so the way you are intending to use is NOT valid. I have edited my answer to reflect that.

Is correct to place a switch-block inside another one?

I shall provide a piece of code from one method, where I'm trying to handle commands/values from the web-service.
switch (cmdName)
{
case "getShapefile":
switch (cmdValue)
{
case "buildings":
HandleShapeFile(ref shapfile);
break;
}
break;
}
The idea is the next:
I have several commands (about 7, e.g. get{X-Object})
Also there are for about 10 values for each command, so the count of operations is: 70, and they are different.
How is better to handle values and develop a fine design of such an aim?
I'd probably use methods for each of the 7.
switch (cmdName)
{
case "getShapefile":
HandleShapeFiles( cmdValue );
break;
}
and then have the second case statement in the method.
So the idea is, 7 methods, each with their own case statement of 10 options.
you could flatten the switch so you would have no need for multiple switch blocks.
switch(cmdName + "-" + cmdValue)
{
case "getShapefile-buildings":
HandleShapeFile(ref shapfile);
break;
}

Switch Case Statement in C#

I need help with a speech recognition program I'm working on in C#.
This refers the the Switch Statement. If we have an example this this:
//FIRST CASE STATEMENT
case "open chrome":
System.Diagnostics.Process.Start(#"C:\Program Files\Google\Chrome\Application\chrome.exe");
JARVIS.Speak("Loading");
break;
//SECOND CASE STATEMENT
case "Thanks":
JARVIS.Speak("No problem");
break;
How do I make it so that if the first case statement is not said then the second one will not work. But if the first case statement IS said then it will allow for the second one to work.
I'm thinking here I need an IF statement but I'm not sure.
Thanks.
How about
//FIRST CASE STATEMENT
case "open chrome":
System.Diagnostics.Process.Start(#"C:\Program Files\Google\Chrome\Application\chrome.exe");
JARVIS.Speak("Loading");
alocalvariable = true;
break;
Outside switch
if (alocalvariable)
{
JARVIS.Speak("No problem");
alocalvariable = false;
}
You didn't really specify this, but the way this is set up, switch 1 will have to be hit one time for every time you want switch 2 to fire:
bool isValid = false;
switch(whateverYourVariableIsCalled)
{
//FIRST CASE STATEMENT
case "open chrome":
System.Diagnostics.Process.Start(#"C:\Program Files\Google\Chrome\Application\chrome.exe");
JARVIS.Speak("Loading");
isValid = true;
break;
//SECOND CASE STATEMENT
case "Thanks":
if (isValid)
{
JARVIS.Speak("No problem");
}
isValid = false;
break;
}
Switch/Case is like if-else statement, it will only execute one case.
You will need a nested if statement to do this.
To make your code more readable and understandable, you can probably make your cases into a function, and calls the function if satisfy certain condition.

Categories

Resources