This question already has answers here:
Control cannot fall through from one case label
(8 answers)
Closed 9 years ago.
I am trying to convert an if statement to switch cases (for readability)
1) I've read switch statements are aweful in general - Is that true?
https://stackoverflow.com/questions/6097513/switch-statement-inside-a-switch-statement-c
2) The statement goes like this:
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
case Display.NonExpense:
if (expected.EXPENSE == true)
break;
case Display.All:
//Code
break;
}
Error is:
Control cannot fall through from one case label ('case 1:') to another
This is the original if statement:
if ((Show == Display.All) || (expected.EXPENSE == true && Show == Display.Expense) || (expected.EXPENSE == false && Show == Display.NonExpense))
{
//Code
}
First off, I notice that you forgot to ask a question in your second point. So I'm going to ask some questions for you addressing your second point:
What is the meaning of the "can't fall through" error?
Unlike C and C++, C# does not allow accidental fall-through from one switch section to another. Every switch section must have an "unreachable end point"; it should end with a break, goto, return, throw or (rarely) infinite loop.
This prevents the common bug of forgetting to put in the break and "falling through" accidentally.
You've written your code as though fall-through is legal; my guess is that you're a C programmer.
How can I force fall-through in C#?
Like this:
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
else
goto case Display.All;
case Display.NonExpense:
if (expected.EXPENSE == true)
break;
else
goto case Display.All;
case Display.All:
//Code
break;
}
Now the reachability analyzer can determine that no matter which branch of the "if" is taken, the switch section endpoint is unreachable.
Is this good style?
No. Your original code was a lot more readable.
I've read switch statements are aweful in general - Is that true?
Opinions vary. Switch statements are very useful when there is a small number of very "crisp" alternatives whose behaviours do not interact in complex ways. Some people will tell you that switched logic should instead be handled by virtual methods or visitor patterns, but that can be abused as well.
Should I use a switch in this particular case?
I wouldn't.
How would you improve my code?
if ((Show == Display.All) ||
(expected.EXPENSE == true && Show == Display.Expense) ||
(expected.EXPENSE == false && Show == Display.NonExpense))
{
//Code
}
First off, don't name things IN ALL CAPS in C#.
Second, don't compare Booleans to true and false. They're already Booleans! If you want to know the truth of statement X you would not say in English "is it true that X is true?" You would say "Is X true?"
I would likely write:
if (Show == Display.All ||
Show == Display.Expense && expected.Expense ||
Show == Display.NonExpense && !expected.Expense)
{
//Code
}
Or, even better, I would abstract the test away into a method of its own:
if (canDisplayExpenses())
{
//Code
}
Or abstract the whole thing away:
DisplayExpenses();
The compiler will not understand what you mean here.
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
// missing break here
case Display.NonExpense:
The compiler will not connect the dots and understand that the break; statement inside your if statement is linked to the switch statement. Instead it will try to link it to a loop, since break; statements on their own can only be used with loops, to break out of it.
That means that your case block is missing its break statement to complete it, and thus the compiler complains.
Instead of trying to wring the necessary code out of a switch statement, I would instead break up your original if statement.
This is yours:
if ((Show == Display.All) || (expected.EXPENSE == true && Show == Display.Expense) || (expected.EXPENSE == false && Show == Display.NonExpense))
{
//Code
}
This is how I would write it:
bool doDisplayExpected =
(Show == Display.All)
|| (Show == Display.Expense && expected.EXPENSE)
|| (Show == Display.NonExpense && !expected.EXPENSE);
if (doDisplayExpected)
{
// code
}
You don't have to pack everything on one line.
Also, I would try to name properties so that they're easier to read, I would rename the EXPENSE property to IsExpense so that the above code would read like this:
bool doDisplayExpected =
(Show == Display.All)
|| (Show == Display.Expense && expected.IsExpense)
|| (Show == Display.NonExpense && !expected.IsExpense);
if (doDisplayExpected)
{
// code
}
Then, ideally, I would refactor out the sub-expressions to methods:
bool doDisplayExpected =
ShowAll()
|| ShowExpense(expected)
|| ShowNonExpense(expected);
if (doDisplayExpected)
{
// code
}
public bool ShowAll()
{
return Show == Display.All;
}
public bool ShowExpense(Expected expected)
{
return Show == Display.Expense && expected.EXPENSE;
}
public bool ShowNonExpense(Expected expected)
{
return Show == Display.NonExpense && !expected.EXPENSE;
}
Then you can put the expression back into the if-statement:
if (ShowAll() || ShowExpense(expected) || ShowNonExpense(expected))
{
// code
}
This should be easier to read, and change later on.
Use if statements and extract complex conditions into methods, e.g
if (ShowAll() || ShowExpense())
{
}
Remember about OOP and polymorphism every time you write such 'switch', adding another
case to that code will be a nightmare
see this and similar (C++) instructions about converting switches
P.S if you are interested in making your code clean and readable, consider reading Smalltalk Best Practice Patterns by Kent Beck and/or Clean Code by Uncle Bob
I really enjoyed both of them, highly recommend.
If you want readability, just throw away your syntax trash:
if (Show == Display.All || expected.EXPENSE && Show == Display.Expense || !expected.EXPENSE && Show == Display.NonExpense)
{
//Code
}
Provide the else part for each of them so it will not throw error, however as others say, you actually don't need switch in this case.
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
// do what you want
break;
else
// do what you want
break;
case Display.NonExpense:
if (expected.EXPENSE == true)
// do what you want
break;
else
// do what you want
break;
case Display.All:
//Code
break;
}
The reason why you get this error is that you are not defining break statements.
You defined the break conditionally.
switch (Show)
{
case Display.Expense:
if (expected.EXPENSE != true)
break;
// Note that the break above is in scope of you if statement, and will
// result in a compiler error
case Display.NonExpense:
...
}
Either make sure every case statement has its own break or group the case statements as follows.
switch (Show)
{
case Display.Expense:
case Display.All:
// do stuff
// Expense and All have the same behavior
}
Refactor out the if statements so you can express it like so:
if (isDisplayAll() || isExpense(expected) || isNonExpense(expected))
{
// Code
}
The extracted logic:
private bool isDisplayAll()
{
return (Show == Display.All);
}
private bool IsExpense(Expected expected)
{
return expected.EXPENSE && (Show == Display.Expense);
}
private bool IsNonExpense(Expected expected)
{
return !expected.EXPENSE && (Show == Display.NonExpense);
}
Agree with Dennis, you don't want a switch case for this problem.
Although probably less readable, you can also use shorter:
if (Show == Display.All || (expected.EXPENSE == (Show == Display.Expense)))
{
//Code
}
Related
I am using a switch and get a warning that code is unreachable.
If control goes to case 2 or 3, something will get execute then what is the issue?
While executing case "2" and case "3", your function pointer will never reach break statement because of goto statements in if..else conditions.
It is unreachable, the if statement above it will always redirect with the gotos.
You could just refactor the logic into a simple if statement..
var cemValIsOne = hdnCEMStatus.Value == "1";
var cemIDIsZeroOrEmpty = hdmCEMID.Value == "" || hdmCEMID.Value == "0";
if(cemValIsOne || (!cemValIsOne && !cemIDIsZeroOrEmpty))
{
// case 1 code...
}
else
{
// case 0 true if statement code
}
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;
}
Suppose I have a long, complex list of conditions, which must be true in order for an if statement to run.
if(this == that && foo != bar && foo != that && pins != needles && apples != oranges)
{
DoSomethingInteresting();
}
Typically, if I'm forced into doing something like this, I'll just put each statement on its own line, like this:
if
(
this == that
&& foo != bar
&& foo != that
&& pins != needles
&& apples != oranges
)
{
DoSomethingInteresting();
}
But I still feel this is a bit of a mess. I'm tempted to refactor the contents of the if statement into its own property like this
if(canDoSomethingInteresting)
{
DoSomethingInteresting();
}
But then that just moves all the mess into canDoSomethingInteresting() and doesn't really fix the problem.
As I said, my goto solution is the middle one, because it doesn't obfuscate the logic like the last one and is more readable than the first. But there must be a better way!
Example in response to Sylon's comment
bool canDoSomethingInteresting
{
get{
//If these were real values, we could be more descriptive ;)
bool thisIsThat = this == that;
bool fooIsntBar = foo != bar;
bool fooIsntThat = foo != that;
return
(
thisIsThat
&& fooIsntBar
&& fooIsntThat
);
}
}
if(canDoSomethingInteresting)
{
DoSomethingInteresting();
}
In my opinion moving the mess into a Property or a Method is not that bad an idea. That way it is self contained and your main logic where you do the if(..) check becomes more readable. Especially if the list of conditions to check is huge, it is better off being in a property, that way if you need to re-use that you are not duplicating that check.
if(IsAllowed)
{
DoSomethingInteresting();
}
Containing the code for the different conditions in separate vars is a great way to go for readability and maintainability. When your vars are named good you get
if (goToNextPage)
{
if (notAdmin)
{
RedirectToNormalPage();
}
else
{
RedirectToAdminPage();
}
}
Compared to something like this
if ((x == 1) && ((y == 'r') || (y == 't')))
{
if (!a)
{
RedirectToNormalPage();
}
else
{
RedirectToAdminPage();
}
}
I will let you choose which one you would want to read when you go back to your code at a later date.
Method is good. Better method name would tell what it tests, not what can be done if it is true. Like
if (isFooValid()) { mergeFoo(); }
If it fits logically to the code flow and especially if I don't care if it is done or not at that point, I also often wrap whole if to a method:
maybeMergeFoo();
The key is to mentally step back and look what fits best to the current code, and to the code you are going to write next. Often it is then clear what is the right way to organize the code.
I am convertng vb.net to c# 2010 as my job, and none of the automatic tools I have can succeed completely. In special example, this case:
'searchString is a string paramter from a long method
Select Case searchString
Case "paid"
'Do something long here
Case "oaaaaa" To "ozzzzzz", "maaaaaa" To "mzzzzzz"
'Do other long code
Case Else
'other long code
End Select
I am mostly java developer before this, so not great with c# and none with vb.net. I do not understand the "oaaaa to ...." part and this part is not converting. Can you please point me to right place to find the c# version of this?
There isn't a direct equivalent in C# but you can easily achieve the same semantics (with more readable code!) using the following:
if(searchString == "paid") {
// do something here
}
else if(
searchString.IsInRange("oaaaaa", "ozzzzzz") ||
searchString.IsInRange("maaaaa", "mzzzzzz")
) {
// do other long code
}
else {
// other long code
}
public static class StringExtensions {
public static bool IsInRange(this string s, string lower, string upper) {
if(String.Compare(lower, upper) > 0) {
throw new InvalidOperationException();
}
return String.Compare(s, lower) >= 0 && String.Compare(s, upper) <= 0
}
There's no direct C# equivalent of the Case "xxx" To "yyy" syntax. I suppose the closest translation will probably be an if/else if/else stack:
if (seachString == "paid")
{
// do something long here
}
else if (((searchString.CompareTo("oaaaaaa") >= 0) && (searchString.CompareTo("ozzzzzz") <= 0))
|| ((searchString.CompareTo("maaaaaa") >= 0) && (searchString.CompareTo("mzzzzzz") <= 0)))
{
// do other long code
}
else
{
// other long code
}
C# doesn't seem to have the concept of Case ... To. See http://msdn.microsoft.com/en-us/library/cy37t14y(VS.80).aspx. The C# example says "This language is not supported".
bitwise has the answer, but here is the translated code (it's just like javascript):
switch (searchString){
case: "paid"
'Do something long here
break;
case: "oaaaaa" To "ozzzzzz", "maaaaaa" To "mzzzzzz"
'Do other long code
break;
default:
'other long code
break;
}
I'm dealing with a program that does plenty of if...else branching based on command line arguments. This is in C# but I'm sure it's applicable to Java, C++ etc. Here's the general outline:
if (args.Length == 0)
{
//do something
}
if (args.Length > 0 && args.Length < 2)
{
Console.WriteLine("Only one argument specified. Need two arguments");
return 0;
}
else if (args.Length > 0 && args.Length >= 2)
{
//Process file - Argument 1
if(args[0].Trim() == PROCESS_OPTION_ONE
|| args[0].Trim() == PROCESS_OPTION_TWO)
{
//Process file - Argument 2
if(args[1].Trim() == PROCESS_CUSTOMER
|| args[1].Trim() == PROCESS_ADMIN
|| args[1].Trim() == PROCESS_MEMBER
|| args[1].Trim() == PROCESS_GUEST
|| args[1].Trim() == PROCESS_USER
)
{
So as you can tell, it's kind of a mess. Is there a design pattern or two that would be most applicable toward cleaning things up some? Command pattern, perhaps? Thanks for the advice and tips.
Stop nesting.
You can switch like (+1) Joel said, or you can just break your logic into clear method calls.
if(args.Length <= 1)
{
Console.WriteLine("Need 2 args kthx");
return;
}
if(args.Length > 2)
{
Console.WriteLine("More than 2 args don't know what do");
return;
}
var arg1 = args[0].Trim();
var arg2 = args[1].Trim();
switch(arg1)
{
case PROCESS_OPTION_ONE:
ProcessOptionOne(arg2);
break;
case PROCESS_OPTION_TWO:
ProcessOptionTwo(arg2);
break;
default:
Console.WriteLine("First arg unknown I give up");
return;
}
then, in your process methods...
private static void ProcessOptionTwo(string argumentTwo)
{
if(argumentTwo == PROCESS_CUSTOMER ||
argumentTwo == PROCESS_ADMIN ||
/* etc blah blah */
}
Keep your methods as simple as possible and break up longer, confusing algorithms into distinct method calls which, through their name, give a clear indication of what they are doing.
I'm partial to using switch statements on the arguments array and setting properties in a configuration class of some kind for each anticipated argument. It appears you're expecting a very specifically formatted argument string rather than allowing set values, you could try:
if(args[0].Trim() == PROCESS_OPTION_ONE || args[0].Trim() == PROCESS_OPTION_TWO)
{
//Process file - Argument 2
switch(args[1].Trim()
{
case PROCESS_CUSTOMER, PROCESS_ADMIN, PROCESS_MEMBER, PROCESS_GUEST, PROCESS_USER:
// Do stuff
break;
default:
// Do other stuff
break;
}
}
My preferred method would be something like
foreach(string arg in args)
{
switch(arg)
{
case PROCESS_CUSTOMER:
// Set property
break;
...
default:
// Exception?
break;
}
}
NOTE: args.Length == 1 is faster than args.Length > 0 && args.Length < 2. It's also a little more readable.
You don't need the else if you've already returned. That might cut out a lot of your nesting. You could also try using a switch instead of a bunch of nested ifs.
I took the code from this Code Project article a long time ago and made my own version of it to use for command line applications. I did my own modifications to it, like making the class inherit from Dictionary, etc. But the regex part of the code is very good, and makes these sort of command line switches easy as pie.