How to break out of multiple loops at once in C#? - c#

What if I have nested loops, and I want to break out of all of them at once?
while (true) {
// ...
while (shouldCont) {
// ...
while (shouldGo) {
// ...
if (timeToStop) {
break; // Break out of everything?
}
}
}
}
In PHP, break takes an argument for the number of loops to break out of. Can something like this be done in C#?
What about something hideous, like goto?
// In the innermost loop
goto BREAK
// ...
BREAK: break; break; break;

Extract your nested loops into a function and then you can use return to get out of the loop from anywhere, rather than break.

Introduce another control flag and put it in all your nested while condition like below. Also replaces the while(true) condition you have with that
bool keepLooping = true;
while (keepLooping) {
// ...
while (shouldCont && keepLooping) {
// ...
while (shouldGo && keepLooping) {
// ...
if (timeToStop) {
keepLooping = false;
break; // break out of everything?
}
}
}
}

Goto is only hideous when abused. To drop out of the innermost loop of some nesting it's acceptable. BUT... one has to ask why there is so much nesting there in the first place.
Short answer: No.

If you want to break out of an entire method, then use the code below.
If you only want to break out of a series of loops within a method without breaking out of the method, then one of the answers that have already been posted will do the job.
if (TimeToStop)
{
return;
}

You can just use goto to get out of the loops:
[...]
while (true) {
// ...
while (shouldCont) {
// ...
while (shouldGo) {
// ...
if (timeToStop) {
goto GETOUT;
}
}
}
}
GETOUT:
//move on to the next step
[...]

Related

Question about else statement following if-else

I'm brushing up on some C# and had a question that seemed dumb. In C# (and probably most languages), can you put an else statement inside an if-else statement?
e.g.
if (clause) {
execute code
}
else if (clause) {
execute code
else {
execute code
}
}
This should be erroneous.
You probably want something like this instead:
if (clause)
{
// do something
}
else
{
if (anotherClause)
{
// do something
}
else
{
// do something
}
}
I assume you are new to programming, so I can talk a little bit about if else statements.
else does not make any sense when you don't have an if before it.
For example,
This statement makes sense:
IF you are 21 or older, you can drink. ELSE, you cannot drink.
While this does not:
ELSE, you cannot drink
Hopefully my answer helps
it is not possible but you can do something like that instead :
if(condition)
{
//code that get executed after cheking the condition
}
else if(another condition)
{
// code that get executed after checking the second condition
}
else
{
// code get executed if the first and the second condition are not true
}
That code wouldn't work because you need an if for there to be an else. If you want to do an additional check for something within the else if, you need to add an if first, like this:
if (clause)
{
execute code
}
else if (clause)
{
execute code
if (clause)
{
execute code
}
else
{
execute code
}
}

How to use a Func or Action in a loop instead of local variables?

I'm refactoring some old code and I have the following loop:
while (true)
{
if (stopLoop.IsStopRequested || ct.IsCancellationRequested)
{
break;
}
if (worker.IsPaused)
{
Thread.Sleep(delay);
continue;
}
if (wait)
{
Thread.Sleep(delay);
wait= false;
continue;
}
//much more code here...
}
I would like to combine the isPaused and wait into one block and was thinking of using a Func.
Would this make sense in this particular case? How would such a Func loop like?
Can you replace it with one if-condition?
if (wait || worker.IsPaused)
{
Thread.Sleep(delay);
wait = false;
continue;
}
If wait is true you always set it to false. If it's false you will set it to false again.

Stop or continue execution of a loop based on variable value

I've different thread which contains an infinite loop, inside each loop I call this method that return a true or false based on specific condition, but I'm going to return true just for example:
public void Test()
{
return true;
}
I'm wondering if can I break or continue the execution of the loop in a quick way, I mean, without write in any loop this condition:
if(Test())
{
break;
}
If I catch your meaning, you probably want to do the work while Test() is not returning false:
do
{
//your stuff
} while (Test());
Or if you won't necessarily iterate even once:
while(Test())
{
//your stuff
}

How to stop execution of if-statement

Hi I want to stop the execution of if-loop ,I have tried with 'return' statement but its exits from the function ,So how can I exit from the single if Statement.I have tried with following code...
Here I want to stop execution of if(CheckHorizontalSide(SourceMember)) and by stopping this I want to move towards the if(CheckTop(SourceMember))
void A()
{
if (CheckHorizontalSide(SourceMember))
{
if (lblHorizontalMember.Text == DestinationMember)
{
lsRelationPath.Add(lblHorizontalMember.Text);
lblRelationPath.Text = String.Join("-", lsRelationPath);
lblRelationPath.Visible = true;
return;
}
bool WhetherContains = lsRelationPath.Contains(SourceMember);
if (WhetherContains)
{
return;
}
//This below code is not related to the above 'WhetherContains '
lsMemberID1.Clear();
lsRelationPath.Add(lblHorizontalMember.Text);
Find_Route(lblHorizontalMember.Text, DestinationMember);
}
if(CheckTop(SourceMember))
{
//code here....
}
}
You put the rest of the block in a sub-block with { } and put else in front of that.
You can nest as deeply as you want but you might try factoring out blocks to helper functions to reduce the complexity and give statements a name.
if (WhetherContains)
{
// this is actually empty
}
else
{
lsMemberID1.Clear();
lsRelationPath.Add(lblHorizontalMember.Text);
}
Or,
if (!WhetherContains)
{
lsMemberID1.Clear();
lsRelationPath.Add(lblHorizontalMember.Text);
}

Continue in nested while loops

In this code sample, is there any way to continue on the outer loop from the catch block?
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// how do I continue on the outer loop from here?
continue;
}
}
}
UPDATE: This question was inspiration for my article on this subject. Thanks for the great question!
"continue" and "break" are nothing more than a pleasant syntax for a "goto". Apparently by giving them cute names and restricting their usages to particular control structures, they no longer draw the ire of the "all gotos are all bad all the time" crowd.
If what you want to do is a continue-to-outer, you could simply define a label at the top of the outer loop and then "goto" that label. If you felt that doing so did not impede the comprehensibility of the code, then that might be the most expedient solution.
However, I would take this as an opportunity to consider whether your control flow would benefit from some refactoring. Whenever I have conditional "break" and "continue" in nested loops, I consider refactoring.
Consider:
successfulCandidate = null;
foreach(var candidate in candidates)
{
foreach(var criterion in criteria)
{
if (!candidate.Meets(criterion))
{ // TODO: no point in continuing checking criteria.
// TODO: Somehow "continue" outer loop to check next candidate
}
}
successfulCandidate = candidate;
break;
}
if (successfulCandidate != null) // do something
Two refactoring techniques:
First, extract the inner loop to a method:
foreach(var candidate in candidates)
{
if (MeetsCriteria(candidate, criteria))
{
successfulCandidate = candidate;
break;
}
}
Second, can all the loops be eliminated? If you are looping because you are trying to search for something, then refactor it into a query.
var results = from candidate in candidates
where criteria.All(criterion=>candidate.Meets(criterion))
select candidate;
var successfulCandidate = results.FirstOrDefault();
if (successfulCandidate != null)
{
do something with the candidate
}
If there are no loops then there is no need to break or continue!
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// how do I continue on the outer loop from here?
goto REPEAT;
}
}
// end of outer loop
REPEAT:
// some statement or ;
}
Problem solved. (what?? Why are you all giving me that dirty look?)
You can use a break; statement.
while
{
while
{
try
{
throw;
}
catch
{
break;
}
}
}
Continue is used to jump back to the top of the current loop.
If you need to break out more levels than that you will either have to add some kind of 'if' or use the dreaded/not recommended 'goto'.
Swap the try/catch structure with the inner while loop:
while {
try {
while {
throw;
}
}
catch {
continue;
}
}
No.
I suggest, extracting the inner loop into a separate method.
while
{
// outer loop
try
{
myMethodWithWhileLoopThatThrowsException()
}
catch
{
// how do I continue on the outer loop from here?
continue;
}
}
}
Use break in the inner loop.
You just want to break from the inner which would continue the outer.
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// how do I continue on the outer loop from here?
break;
}
}
}
I think the best way to accomplish this would be to use the break statement. Break ends the current loop and continues execution from where it ends. In this case, it would end the inner loop and jump back into the outer while loop. This is what your code would look like:
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// break jumps to outer loop, ends inner loop immediately.
break; //THIS IS THE BREAK
}
}
}
I believe that is what you were looking to be accomplished, correct?
Thanks!
using System;
namespace Examples
{
public class Continue : Exception { }
public class Break : Exception { }
public class NestedLoop
{
static public void ContinueOnParentLoopLevel()
{
while(true)
try {
// outer loop
while(true)
{
// inner loop
try
{
throw new Exception("Bali mu mamata");
}
catch (Exception)
{
// how do I continue on the outer loop from here?
throw new Continue();
}
}
} catch (Continue) {
continue;
}
}
}
}
}
Use an own exception type, e.g., MyException. Then:
while
{
try {
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// how do I continue on the outer loop from here?
throw MyException;
}
}
} catch(MyException)
{ ; }
}
This will work for continuing and breaking out of several levels of nested while statements.
Sorry for bad formatting ;)

Categories