Does anyone still use [goto] in C# and if so why?
C#.NetCoding StyleGotoC# Problem Overview
I was wondering whether anyone still uses the "goto" keyword syntax in C# and what possible reasons there are for doing so.
I tend to view any statements that cause the reader to jump around the code as bad practice but wondered whether there were any credible scenarios for using such a syntax?
C# Solutions
Solution 1 - C#
There are some (rare) cases where goto can actually improve readability. In fact, the documentation you linked to lists two examples:
> A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement. > > The goto statement is also useful to get out of deeply nested loops.
Here's an example for the latter one:
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
Of course, there are other ways around this problem as well, such as refactoring the code into a function, using a dummy block around it, etc. (see this question for details). As a side note, the Java language designers decided to ban goto completely and introduce a labeled break statement instead.
Solution 2 - C#
I remember this part
switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
To something like this
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
Refer This
Solution 3 - C#
I use it extensively in Eduasync to show the kind of code that the compiler generates for you when using async methods in C# 5. You'd see the same thing in iterator blocks.
In "normal" code though, I can't remember the last time I used it...
Solution 4 - C#
The compiler uses goto
statements in various pieces of generated code, for example in generated iterator block types (generated when using the yield return
keyword - I'm pretty sure that the generated XML serialisation types also have a few goto
statements in there somewhere too.
See Iterator block implementation details: auto-generated state machines for some more details on why / how the C# compiler handles this.
Other than generated code there isn't a good reason to use a goto
statement in normal code - it makes the code harder to understand and as a result more error-prone. On the other hand using goto
statements in generated code like this can simplify the generation process and is normally fine because nobody is going to read (or modify) the generated code and there is no chance of mistakes being made because a machine is doing the writing.
See Go-to statement considered harmful for an argument against goto
as well as a classic piece of programming history.
Solution 5 - C#
I don't remember ever using goto
. But maybe it improves the intent of a forever loop that you really never want to exit (no break
, but you can still return
or throw
):
forever: {
// ...
goto forever;
}
Then again, a simple while (true)
should suffice...
Also, you could use in a situation where you want the first iteration of a loop to start in the middle of the loop: look here for an example.
Solution 6 - C#
goto is great for breaking out of many loops where break would not work well (say upon error conditions), and as Kragen said goto is used by the compiler to generate switch statements and some other things as well.
Solution 7 - C#
The processor implements at least one jump instruction and I'm sure lots of statements use those in thier implementation or interpretation.
One of the good things about using a 3rd or 4th generation langauge is that these physical details are abstracted away from us. Whilst we should be mindful of the law of leaky abstraction I think that we should also use our tools as they are intended (sorry). If I were writing code and a goto
seemed like a good idea, it would be time to refactor. The purpose of a structured language is to avoid these "jumps" and to create a logical flow in our engineering.
I should avoid the use of break
but I can't overlook the performance benefit. However, if I have nested loops that mutually need to break
it is time to refactor.
If anybody can propose a use of goto
that seems better than refactoring I will gladly withdraw my answer.
I hope I'm not guilty of rushing to the "bike shed" here. Like Kragen says, whats good enough for Dijkstra is good enough for me.
Solution 8 - C#
Goto is never better. And continue, break (except in switch/case), (multiple) return, and throw should also be kept to the barest minimum. You never want to escape from the middle of nest loops. You always want the loop control statements have all the loop control. Indenting has information, and all these statement throw that information away. You might as well take out all the indenting.