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 ;)
Related
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
}
}
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
}
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);
}
I have a function like this:
foreach (ListViewItem item in getListViewItems(listView2)) //for proxy
{
if (reader.Peek() == -1)
{
break;
}
lock (reader)
{
line = reader.ReadLine();
}
//proxy code
List<string> mylist = new List<string>();
if (item != null)
{
for (int s = 0; s < 3; s++)
{
if (item.SubItems[s].Text != null)
{
mylist.Add(item.SubItems[s].Text);
}
else
{
mylist.Add("");
}
}
}
else
{
break;
}
//end proxy code
//some other code including the threadpool
}
and the delegate code:
private delegate ListView.ListViewItemCollection GetItems(ListView lstview);
private ListView.ListViewItemCollection getListViewItems(ListView lstview)
{
ListView.ListViewItemCollection temp = new ListView.ListViewItemCollection(new ListView());
if (!lstview.InvokeRequired)
{
foreach (ListViewItem item in lstview.CheckedItems)
{
temp.Add((ListViewItem)item.Clone());
}
return temp;
}
else
{
return (ListView.ListViewItemCollection)this.Invoke(new GetItems(getListViewItems), new object[] { lstview });
}
}
EDIT:
I wanna replace that foreach loop in the main function with a conditional function:
if (reader.Peek() == -1)
{
break;
}
lock (reader)
{
line = reader.ReadLine();
}
if (use_proxy == true)
{
mylist2 = get_current_proxy();
}
//some other code including the threadpool
private List<string> get_current_proxy()
{
//what shall I add here?
}
How can I make that function do the same as foreach loop but using for loop? I mean getting the proxies one by one ...
I see multiple questions revolving around an idea of scraping a website for emails then spamming. You have very cool tools for that already, no need for a new one.
Anyway - I don't understand your question, and it seems that I'm not the only one here, but the thing you'll have to KNOW before anything else is:
Having ANYTHING in Windows run in multiple threads will ultimately have to be synchronized when you do Invoke() which HAVE TO wait until it all passes through ONE thread and that's the one that holds a message loop. So you can try to read from or write to ListView from multiple threads, but to do each read/write you'll have to Invoke() (you probably tried it directly and BAAAAM) and every Invoke() has only ONE hole to go through, and all your threads will have to wait their turn.
Next: having ListView to be a CONTAINER for your data is so BAD I can't even comment any further. Consider something as a
class MyData
{
public string Name;
public string URL;
// ...
}
and
List<MyData> _myData;
to hold your data. You'll be able to access it from multiple threads, if you take care of some low-key sync issues.
Lastly, how come you ask us questions about .net C# programming if you don't even know the syntax. Well, it's rhetorical, ...
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
[...]