Reputation: 671
I have read multiple articles saying using goto is a massive no no in programming. But some specifically indicate that it's the abuse of goto that is wrong and that in some cases, like switch cases, it's the intended use.
So my question to you is, for future reference, which is best practice/more efficient.
this:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
break;
default:
//Something specific for default
goto case 2;
}
or this:
switch (a)
{
case 1:
//Something specific for case 1
break;
case 2:
//Something specific to default and case 2
thatFunction();
break;
default:
//Something specific for default
thatFunction();
break;
}
void thatFunction() { /*Case 2 stuff*/ }
EDIT: These two switch statements are examples, the actual code contains many more cases.
Everyone at my workplace has either never used goto or say they've only heard to never ever use it. So I came here for a definitive answer. I'm looking for an answer and an explanation or links to one. Thanks,
Upvotes: 1
Views: 1070
Reputation: 63742
You always need to understand the reasoning behind any "no-no" (or "yes-yes"). That way you can understand where it makes sense to apply the rule, and where it doesn't.
The big fight against goto
goes all the way back to programming without true procedures and functions, or even something as simple as a loop. goto
allowed you to jump from anywhere to anywhere else, and it was extremely hard to think about what it actually means. "Don't use goto" was part of the movement to structured code, as opposed to lots of jumps all the way around the code; using things like for (int i = 10; i > 0; i--) { ... }
for iteration, rather than if (i-- > 0) goto startLoop;
.
In a switch
, goto
is constrained - it can only do one thing, execute a branch of the switch
statement. In fact, in C#, even outside of a switch
statement, goto
is very constrained and safe, and rarely has any of the implications that were assumed when the "Goto is evil" movement started. That doesn't mean you should start replacing all your loops with goto
s, of course :)
Now, if things are getting this complicated, it might be that a switch
isn't a good solution for your problem in the first place. Perhaps you can use a different structure to do what you're trying to do - there's many ways to do polymorphism and/or code reuse in C#, and one of those might be a better approach that will allow you to use clearer code to do what you're trying to do. But we can't really help you with that :)
Upvotes: 3
Reputation: 1950
The answer is that logic going in circles is best kept to religion and politics. Your default
is really case 2
, which means that case 2
is really just default
. While it's possible that there's some execution in case 2
that doesn't occur in default
, it's extremely rare that you'd ever need to do anything other than an if
condition in your default
case. Further, in troubleshooting the result of your switch
evaluation cannot be immediately determined if you loop backward up the case chain. Imagine your stack trace, too.
There are times to use goto
, but these are often in exception
al cases (see what I did there) where you need to immediately execute an action (such as logging something going wrong on another thread) before break
ing a run condition or infinite loop. The general rule with goto
is the same as with preprocessor commands. If there's another way you can do the same effective thing, you should use the other way for logical continuity and maintainability.
Upvotes: 1