I've seen a suggested coding standard that reads Never use goto unless in a switch statement fall-through
.
I don't follow. What exactly would this 'exception' case look like, that justifies a goto
?
A label is a valid C# identifier followed by colon. In this case, case and default statements of a Switch are labels thus they can be targets of a goto. However, the goto statement must be executed from within the switch. that is we cannot use the goto to jump into switch statement .
@The Smartest: A switch statement in itself can already have plenty of goto s, but they are named differently: Each break is a goto. @chiccodoro That's nothing, actually each case is a label and switch essentially is a goto . Each break is a goto , but also each continue is a goto too.
Yes, it does.
NOTE − Use of goto statement is highly discouraged in any programming language because it makes difficult to trace the control flow of a program, making the program hard to understand and hard to modify. Any program that uses a goto can be rewritten to avoid them.
This construct is illegal in C#:
switch (variable) {
case 2:
Console.WriteLine("variable is >= 2");
case 1:
Console.WriteLine("variable is >= 1");
}
In C++, it would run both lines if variable = 2
. It may be intentional but it's too easy to forget break;
at the end of the first case label. For this reason, they have made it illegal in C#. To mimic the fall through behavior, you will have to explicitly use goto
to express your intention:
switch (variable) {
case 2:
Console.WriteLine("variable is >= 2");
goto case 1;
case 1:
Console.WriteLine("variable is >= 1");
break;
}
That said, there are a few cases where goto
is actually a good solution for the problem. Never shut down your brain with "never use something" rules. If it were 100% useless, it wouldn't have existed in the language in the first place. Don't use goto
is a guideline; it's not a law.
C# refuses to let cases fall through implicitly (unless there is no code in the case) as in C++: you need to include break
. To explicitly fall through (or to jump to any other case) you can use goto case
. Since there is no other way to obtain this behaviour, most (sensible) coding standards will allow it.
switch(variable)
{
case 1:
case 2:
// do something for 1 and 2
goto case 3;
case 3:
case 4:
// do something for 1, 2, 3 and 4
break;
}
A realistic example (by request):
switch(typeOfPathName)
{
case "relative":
pathName = Path.Combine(currentPath, pathName);
goto case "absolute";
case "expand":
pathName = Environment.ExpandEnvironmentVariables(pathName);
goto case "absolute";
case "absolute":
using (var file = new FileStream(pathName))
{ ... }
break;
case "registry":
...
break;
}
public enum ExitAction {
Cancel,
LogAndExit,
Exit
}
This is neater
ExitAction action = ExitAction.LogAndExit;
switch (action) {
case ExitAction.Cancel:
break;
case ExitAction.LogAndExit:
Log("Exiting");
goto case ExitAction.Exit;
case ExitAction.Exit:
Quit();
break;
}
Than this (especially if you do more work in Quit())
ExitAction action = ExitAction.LogAndExit;
switch (action) {
case ExitAction.Cancel:
break;
case ExitAction.LogAndExit:
Log("Exiting");
Quit();
break;
case ExitAction.Exit:
Quit();
break;
}
In addition to using goto case
, you can goto
a label that is in another case clause:
switch(i) {
case "0":
// do some stuff
break;
case "1":
// other stuff, then "fall through" to next case clause
goto Case2;
case "2":
Case2:
break;
}
This way, you can jump to another case clause without worrying about the value or type of the expression.
Some sort of explicit "fallthrough" keyword that can be substituted for break
would have been nice, though...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With