Usually I will implement switch case in a method that return particular object. Something like below:
private string testing(string input){
switch(input)
{
case "a":
{
....
return "TestingResult";
}
case "b":
{
....
return "TestingResultB";
}
default:
return null;
}
}
Now I'm wondering if it's possible to write a switch case for value assignment purpose? Something like below:
private string testing(string input){
string TEST="";
switch(input)
{
case "a":
{
....
TEST = "TestingResult";
}
case "b":
{
....
TEST = "TestingResultB";
}
default:
}
return TEST;
}
Of cause it can be achieve by simple If-Else statement, this question is for me to understand more functionality of switch case
Of course, after testing it, I receive error
control cannot fall through from one case label('case: "a"') to another
You need to add break; in each case
private string testing(string input){
string TEST="";
switch(input)
{
case "a":
TEST = "TestingResult";
break;
case "b":
TEST = "TestingResultB";
break;
default:
}
return TEST;
}
As others have mentioned, the braces within each case are unnecessary.
Yes you can. You just have to remember to put a 'jump' statement of some kind (this includes break, goto case, return, or throw), after each case label:
private string testing(string input){
string TEST="";
switch(input)
{
case "a":
TEST = "TestingResult";
break;
case "b":
TEST = "TestingResultB";
break;
}
return TEST;
}
Note, the braces here are unnecessary, and the default isn't required in this construction as it will fall through the switch block if it doesn't match any of the cases.
Further Reading
switch (C# Reference)
What you've written is perfectly legitimate, however there is no point doing the value assignment unless you are going to carry on and do some further operations with it before returning.
To help you with becoming more proficient with switch/case statements:
in your first example you don't need the default, just have a final return at the end of the function
in your second example, you don't need the default at all - you do nothing with it
a switch/case is usually used for multiple options, for example 4 or more. Any less than that and an if/else is equally readable. You should also bear in mind that a switch/case can give you good speed improvements in some cases
Related
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;
}
}
case when is fairly new so many answers don't touch upon it. The MSDN example is about casting the object, not using the original string.
switch (catName)
{
case string c when c.StartsWith("Fluffy"):
// DoSomething
break;
}
This seems to work, it'd be nicer if you could omit the string c part and just do when catName instead. But then multiple cases don't work:
switch (catName)
{
case string c when c.StartsWith("Fluffy"):
case string c when c.StartsWith("Mr"):
// DoSomething
break;
}
Because you can't declare two string c. So you could change the second one, but you'd end up with a list of string a, string b, string c etc which doesn't seem very nice.
The ideal way would of course be something like:
switch (catName)
{
case when catName.StartsWith("Fluffy"):
...
break;
}
Is there an elegant way to solve this, or is it simply better to use an if..else if method?
No you can't, because you are using the pattern matching into the switch statement and the type is evaluated at compile time:
expr has a compile-time type that is a base class of type
Anyway, you can use the same variable names because their scope is local. Reference
Edit:
My favourite solution is suggested by kofifus in the comments:
string catName = "Fluffy";
switch (catName)
{
case {} when catName.StartsWith("Fluffy"):
case {} when catName.StartsWith("Mr"):
Console.WriteLine(catName);
break;
default:
Console.WriteLine("Name does not start with Mr or Fluffy.");
break;
}
I know you said two different strings isn't nice, but this looks very readable to me, is there really a problem with doing it like this:
string catName = "Fluffy";
switch (catName)
{
case string c when c.StartsWith("Fluffy"):
case string d when d.StartsWith("Mr"):
Console.WriteLine(catName);
break;
default:
Console.WriteLine("Name does not start with Mr or Fluffy.");
break;
}
Alternatively, based on the 'Reference' link in Krustys answer you could do it like this:
string catName = "Noodle";
switch (catName)
{
case string c when (c.StartsWith("Fluffy") || c.StartsWith("Mr")):
Console.WriteLine(catName);
break;
default:
Console.WriteLine("Name does not begin with Mr or Fluffy.");
break;
}
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.
I was wondering if there is a way to do something like this in c# 7
var test = "aaeag";
switch (test)
{
case test.StartsWith("a"):
break;
default:
break;
}
Sadly it does not look like it possible. Is this correct or am I doing something wrong?
This is possible with C# 7, using a when guard:
var test = "aaeag";
switch (test)
{
case var s when s.StartsWith("a"):
break;
default:
break;
}
What your version of the code is doing is often referred to as active patterns. By eg defining the the extension method:
public static bool StartsWithPattern(this string str, string matchPattern) =>
str.StartsWith(matchPattern);
Then your switch could become:
var test = "aaeag";
switch (test)
{
case StartsWith("a"):
break;
default:
break;
}
If you'd like to see this feature in a future C# version, then please upvote this proposal.
I have written a piece of lousy code in C#.NET and i want to optimize it.
All i can think of at the moment is to separate the common portions into a separate method.
Code :
if(condition1)
{
switch(condition)
case 'A' : //Some code
break;
case 'B' : //Some code
break;
case 'C' : //Some code
break;
}
else if(condition2)
{
switch(condition)
case 'a' : //Some code
break;
case 'B' : //Some code
break;
case 'C' : //Some code
break;
}
Note that the case statements conditions for case 'B' and case 'C' are common.
Any help on improving the code is deeply appreciated.
Why don't you stack the case statements if their code block should do same code
Like this
case 'B' :
case 'C' :
{
//Do Some Code
}
break;
case "a":
case "A":
if ( condition1) {
...
}
else if { condition2}
...
}
break;
All you can do is putting the common code together and check the additional condition there.
switch(condition)
{
case 'A':
if(condition1) //do something
else //do something
break;
case 'a':
same as above
case 'B':
break;
case 'C':
break;
}
I think even if you optimize that piece of code, it would still be very fragile and hard to maintain. I would suggest to try to refactor it using strategy-pattern for example (if it's possible of course).
You would benefit a lot, cause you isolate each routine and do it OOP-way, making it easier to change and maintain in future.