For this program:
class Program
{
static void Main(string[] args)
{
var state = States.One;
switch (state)
{
case States.One:
Console.WriteLine("One");
break;
case States.Zero:
goto case States.One;
}
}
}
public enum States : ulong
{
Zero = 0,
One = 1,
}
I got:
"A switch expression or case label must be a bool, char, string,
integral, enum, or corresponding nullable type"
But state variable is enum type. The error disappears if I comment the goto case line.
I am using VS 2013. + .NET 4.5.1.
This is known bug of the C# compiler when enum is typed as ulong and you use goto case at the same time. If you remove the ulong from enum, it compiles just fine. And because not many people run into this problem, they are not focusing on fixing it.
Depending on your use case, this might also be an option for you:
switch (state)
{
case States.Zero:
case States.One:
Console.WriteLine("One");
break;
}
This should be working according to an example here: http://msdn.microsoft.com/de-de/library/06tc147t.aspx
You could use a label for goto instead of using the case directly in the goto statement:
switch (state)
{
case States.One:
caseZeroRedirect:
Console.WriteLine("One");
break;
case States.Zero:
CouldDoSomethingFirst();
goto caseZeroRedirect;
}
You should try this:-
switch (state)
{
case States.Zero:
case States.One:
Console.WriteLine("1");
break;
}
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;
}
}
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.
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
I have a switch statement:
swtich(x)
{
case 1:
...
break;
case 2:
...
break;
}
I want to put the ... code in a function but I want to put the break too... So I want something like that
void func()
{
...;
break;
}
swtich(x)
{
case 1:
func();
case 2:
func();
}
Break gives error (I know why) but what I can do?
You can't. Best you can do is:
swtich(x)
{
case 1:
func();
break;
case 2:
func();
break;
}
See here for a discussion of what break is for:
The break statement terminates the closest enclosing loop or switch statement in which it appears. Control is passed to the statement that follows the terminated statement, if any.
If you put it in a function, how will it know which loop or switch statement it's supposed to apply to?
You can't put the break in another method.
Though if you want case 1 and case 2 to do the same thing, this is legal:
switch (x)
{
case 1:
case 2:
func();
break;
}
As others have said, it's not possible. Look at it this way, what would be the expected behavior be if you were not inside a switch statement when the execution gets to the break; line?
Put the break; statement after the function call. If you want the function to stop execution under a given condition, use the return; statement.
Don't put the break in the function. Plain and simple.
switch(x)
{
case 1:
func();
break;
case 2:
func();
break;
}