Discussion: C# Break nested loop #6634
Replies: 95 comments 92 replies
-
@Danthekilla, You forgot the existing third way: (bool found, ValueType value) Foo()
{
for (int x = 0; x < xMax; x++)
{
for (int y = 0; y < yMax; y++)
{
var foundValue = GetValue(x, y);
if (foundValue == valueToCompare) return (true, foundValue);
}
}
return (false, default);
} Small focused functions are your friend. But if you want long functions, as you say, there is already two ways of achieving this goal. So I'd see yet another way of achieving it as really bringing nothing to the language. |
Beta Was this translation helpful? Give feedback.
-
Sometimes it's a loop and a switch and coming up with a name for it is super arbitrary and counter-intuitive. |
Beta Was this translation helpful? Give feedback.
-
I'm not in favour of this but I think the following is better
|
Beta Was this translation helpful? Give feedback.
-
I'd prefer to see something like Java Branching Statements, as once pointed out by @HaloFour at #176 (comment) |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
@Logerfo, Indeed, it makes things clear than having something like |
Beta Was this translation helpful? Give feedback.
-
Inline returns slow down loops until .NET Core 2.1 dotnet/coreclr#13314 and functions with a loop generally won't inline (without forcing); so wouldn't be so great for very hot loops; though ok for general loops. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
@bondsbw Not to mention copy/paste. |
Beta Was this translation helpful? Give feedback.
-
This is simple, short and elegant. Goto's require maintenance and their excessive use results in spaghetti code. Extra temp variables hanging around is just junk code that can go wrong. Break = n; in an n deep loop would create short, concise code that cannot be confused for anything else. |
Beta Was this translation helpful? Give feedback.
-
I agree with some of the other posters, I don't like the use of an integer indicating the number of levels. If any enhancements to String foundValue = null;
OUTERLOOP:
for (int x = 0; x < xMax; x++)
{
for (int y = 0; y < yMax; y++)
{
foundValue = GetValue(x, y);
if (foundValue == valueToCompare)
break OUTERLOOP;
}
} This makes it much clearer exactly where the |
Beta Was this translation helpful? Give feedback.
-
I agree that breaking from a named loop is the best option. I think there was a proposal of mine asking for that. Or was it left in the roslyn repo? |
Beta Was this translation helpful? Give feedback.
-
@jnm2 It's better to have an "arbitrary" label and know what it is than having a number and starting to wonder what it means, sometimes. |
Beta Was this translation helpful? Give feedback.
-
@eyalsk Exactly my point. 😄 |
Beta Was this translation helpful? Give feedback.
-
@eyalsk I don't remember preferring numbers but I'm happy to update my opinion if I did write that somewhere. I'm not seeing it. |
Beta Was this translation helpful? Give feedback.
-
That's also because you consider that every programmer works for a company without its own code of conduct, |
Beta Was this translation helpful? Give feedback.
-
Why is it frowned upon? |
Beta Was this translation helpful? Give feedback.
-
This was the first result in Google, there are 1000's more. Personally I think it has its uses and banning it from codebases is going to far, but many disagree. |
Beta Was this translation helpful? Give feedback.
-
GOTO in older languages could be very dangerous. It effectively let you jump anywhere, into and out of functions and other protected areas. The version of GOTO in C# has much stricter guardrails, but that stigma from decades ago remains, likely continuing to be drilled into the minds of students by their professors. You can thank Dijkstra for that. |
Beta Was this translation helpful? Give feedback.
-
That is 'goto' in idl. I'm asking why it's frowned upon in c#. |
Beta Was this translation helpful? Give feedback.
-
I recommend the use of
|
Beta Was this translation helpful? Give feedback.
-
Boy do I with MS would introduce labeled loops. It's literally the one totally valid use-case for Apparently new C# feautres need a 'champion'. Well, I'm not sure why nobody seems to be willing to champion this considering I've seen comments from hundreds of developers who want it. I'll also just mark here that a related discussion is going on at #5525 |
Beta Was this translation helpful? Give feedback.
-
Because it's not the C# language team telling people to not use |
Beta Was this translation helpful? Give feedback.
-
This is puzzling, the utility of an enhanced The I would always favor any change too, that reduced the need to use I wouldn't be surprised either to find that most of the uses of |
Beta Was this translation helpful? Give feedback.
-
I don't think anyone can make a better case, offer better justifications or motivations for a change like this, beyond what has already been presented in this discussion over the past five years, but I'll give it a shot, perhaps, just perhaps it will strike a chord with someone on the language team. There are important distinctions between leveraging a The A Understanding intent in someone's code is extremely important when trying to reason about code, this presumption that RESUME:
if (expression)
{
// stuff
goto RESUME;
} Is to all intents and purposes a If editing some complex set of nested loops within loops and I want to resume some intermediate loop or terminate some intermediate loop then what is easier than just putting a label at the start of the loop and then inserting a With Then what about cases where code gets inadvertently added before or after some label that's used to end or resume a loop? That could easily happen and have subtle effects, while (X)
{
// stuff
for (blah-blah-blah)
{
// stuff
if (Y)
goto EXIT_LOOP; // note this label has no syntactic 'attachment' to the loop were exiting!
}
// Oh dear, I expected this to always execute after I exited the for loop, but that's not true despite the fact it's the next statement right after the loop!
stuff_that_wont_get_done_if_Y_was_true(); // do this right after we leave the loop
EXIT_LOOP: // We get to here when the loop ends, well sometimes we do, but we can get here from many places where a goto gets written.
// stuff
} Can you see? A |
Beta Was this translation helpful? Give feedback.
-
Outside of the current discussion, aimed at people who want this feature, would this be legal code in your proposed view? loop_1:
for (int i = 0; i < 100; i++)
{
loop_2:
for (int j = i; j < 100; j++)
{
for (int k = j; k < 100; k++)
{
// do stuff
continue loop_1;
}
}
}
if (something)
{
goto loop_1;
} i.e. is a "loop label" the same as a "goto label"? |
Beta Was this translation helpful? Give feedback.
-
One could consider not using labels too. One could ponder this for example: while (X)
{
do_this();
while (Y)
{
do_that();
if (J)
break(1); // breaks out of the loop 'while (X)'
}
} Then |
Beta Was this translation helpful? Give feedback.
-
Perhaps its better the other way around: while (X)
{
do_this();
while (Y)
{
do_that();
if (J)
break(0); // breaks out of the loop 'while (X)'
}
} The outermost loop being always |
Beta Was this translation helpful? Give feedback.
-
Edit: This is a suggestion/example that allows you to break out to any level in a nested loop. I updated the sample code to be a little more clean & precise. First, you have an enum:
Then you can control where/when it breaks out:
|
Beta Was this translation helpful? Give feedback.
-
I like not needing to invent a label, but I propose we use additional C# specific keywords. Instead of just However, if you are thinking that this is getting ridiculous, it probably is after three breaks. If you have to pump the breaks that many times and still haven't stopped you need to try something else, and all that is left is to swerve into a tree on the side of the road, which is technically a crash. So, we add the if (x > y)
break break break crash; That should be enough for any scenario. |
Beta Was this translation helpful? Give feedback.
-
@Danthekilla commented on Thu Aug 31 2017
In C# it would be fanstastic to have a language feature (probably syntactic sugar) that lets you break nested loops.
Currently these are the 2 ways you can break out of nested loops:
I would like to propose the ability for a break to have a value for how many loops to break out of. Like so:
Not only is it slightly smaller, but I think easier to read.
Anyone have any thoughts on the matter?
Beta Was this translation helpful? Give feedback.
All reactions