I have a C# while loop, does a continue in this loop issue the same behaviour as moving to the next item in the loop? Exactly the same as for a "for loop".
For example see any problems in the following code sample?
while ((line = file.ReadLine()) != null)
{
string messageDownloadID = line ;
if (String.IsNullOrEmpty(messageDownloadID))
{
continue;
}
}
Thanks in advance.
I have a C# while loop, does a continue in this loop issue the same behaviour as moving to the next item in the loop? Exactly the same as for a "for loop".
No, a continue does not have the behavior of moving to the next item unless the part of the while block that moves to the next item is part of the loop condition or occurs and is executed before the continue statement. A continue will move you to the next iteration of the loop. The continue statement always starts a new iteration in the nearest enclosing while, do, for or foreach statement. But if in a while loop, say, i++ occurs after the continue statement it will not be executed. It is NOT exactly the same as a for loop.
The semantics of continue are like so:
while(condition) {
statement
continue
statement
}
is equivalent to
top:
while(condition) {
statement
goto top;
statement
}
In this case, the statements after the continue will never be executed if the continue is executed. But, for example, these two loops have different semantics:
for (int i = 0; i < 10; i++) {
if (i == 5) {
continue;
}
Console.WriteLine(i);
}
int j = 0;
while (j < 10) {
if (j == 5) {
continue;
}
Console.WriteLine(j);
j++;
}
The former loop will print 0 through 9 on the console while the second will enter an infinite loop after print 0 through 4 on the console.
For example see any problems in the following code sample?
while ((line = file.ReadLine()) != null) {
string messageDownloadID = line;
if (String.IsNullOrEmpty(messageDownloadID)) {
continue;
}
}
Well, it depends. First, this loop isn't doing anything really except moving the file pointer in file to the end of the file. Now, assuming that you meant to have statements after the if statement like so
while ((line = file.ReadLine()) != null) {
string messageDownloadID = line;
if (String.IsNullOrEmpty(messageDownloadID)) {
continue;
}
ProcessMessageDownloadID(messageDownloadID);
}
then your code is fine. This is because the part of the while that moves to the next item is part of the while condition (see my bolded statement above) and thus will be executed every iteration of the loop. Your code is a standard pattern for parsing a file and skipping over items that can't be parsed (because they are, say, blank).
Yes, continue moves to the next iteration of the loop.
Yes, a continue call will restart the loop. Kind of like a goto to a label at the start of the loop.
Yes.
"A while loop can be terminated when a break, goto, return, or throw statement transfers control outside the loop. To pass control to the next iteration without exiting the loop, use the continue statement."
Related
Hi guys how can you repeat one iteration in a foreach?
foreach (string line in File.ReadLines("file.txt"))
{
// now line == "account", next line == "account1"
if (line.Contains("a"))
//next loop take "account1";
else
// need to set that next loop will take line == "account" again
}
How to do it?
While I don't fully understand your example, I think I understand your question. I had the same problem and was able to come up with a solution: include a while loop within the foreach. In your example it would look like this:
foreach (string line in File.ReadLines("file.txt"))
{
bool repeat = true;
while (repeat)
{
// now line == "account", next line == "account1"
if (line.Contains("a"))
{
//do your logic for a break-out case
repeat = false;
}
else
{
//do your logic for a repeat case on the same foreach element
//in this instance you'll need to add an "a" to the line at some point, to avoid an infinite loop.
}
}
}
I know I'm very late to the game, but hopefully this will be helpful for anyone else who stumbles in here with the same problem.
There is no need to change your code, assuming it only has an if/else construct in the loop.
When the if condition evaluates to true the else will not execute and the loop resumes.
In a more complex where you want to immediately resume the loop and ensure nothing else following the condition executes, use the continue statement:
The continue statement passes control to the next iteration of the enclosing while, do, for, or foreach statement in which it appears.
foreach (string line in File.ReadLines("file.txt"))
{
// now line == "account", next line == "account1"
if (line.Contains("a"))
continue;
else
// need to set that next loop will take line == "account" again
// more stuff that we don't want to execute if line.Contains("a")
}
I guess this might also helpful if someone else come
for (int i = 0; i < inventoryTimeBlocks.Count; i++)
{
if (line.Contains("a"))
//next loop take "account1";
else
{
if(i > 0)
{
i = i - 1;
continue;
}
}
}
Is there an equivalent method of performing the job of redo in C#? i.e. going back to the top of the loop and re-execute without checking conditions or increasing the loop counter. Thanks.
for (int i = 0; i < 100; i++)
{
do
{
DoYourStuff();
} while (ShouldWeDoThatAgain());
}
Do...while is like a standard while loop, except instead of checking its conditional before each iteration, it checks after. That way, the code inside the loop will always execute at least once. Stick that inside a for or foreach loop, and that should get you the behavior your want. This is a bit simpler than Simon's answer, as it doesn't require an extra variable, doesn't use continue, and doesn't mess with the loop counter at all.
Why not simply:
Although goto is not really everyone's favourite, it's quite readable in this case...
for(...)
{
redo:
//...
if (...)
goto redo;
}
No. The closest you'll get is something like this:
bool redoCalled = false:
for (int i = 0; i < 10; i++) {
if (redoCalled) {
i--;
redoCalled = false;
}
// other stuff here
if (redoWanted) {
redoCalled = true;
continue;
}
}
I'm trying to run a basic loop that will find a specific value in a dataview grid. I cannot figure out whats going on with the code, since the for loop exits before evaluating its basic condition.
private void SearchDataViewGrid(string FileName)
{
//finds the selected entry in the DVG based on the image
for (int i = 0; i == dataPartsList.Rows.Count ; i++)
{
if(FileName == dataPartsList.Rows[i].Cells[3].Value.ToString())
{
dataPartsList.Rows[i].Selected = true;
}
}
}
The program doesn't crash, but i get an error on my 'i' variables declaring that it has been optimised away. Tried a few easy fixes i found online but nothing seems to keep it.
I have verified that the string i am passing is the correct one, and my 'dummy' DVG returns a value of 14 for the number of rows contained. Even if i remove the 'if' statement inside of the for loop, i still get the same error.
The condition cond in the middle of for(init; cond; update) is not an until condition but a while condition.
So you need to change it to
for (int i = 0; i < dataPartsList.Rows.Count ; i++)
The problem is your conditional is i == dataPartsList.Rows.Count so the body will only execute when these two values are equal. This guarantees your loop will never execute. You need to change your conditional to be < instead of ==
for (int i = 0; i < dataPartsList.Rows.Count ; i++) {
...
}
I am writing a for loop with multiple if statements.
Is it possible that if the if statement (or one part of it) in the for statement evaluates to false, then the loop does not exit but the integer to iterates increments by one and continues through the loop (I need functionality like the continue; keyword).
Example:
for (int i = 0; i <= Collection.Count && Collection[i].Name != "Alan"; i++)
{
// If name is not Alan, increment i and continue the loop.
}
Is this possible?
Thanks
You need functionality like the continue keyword - have you considered using the continue keyword, then?
Update: Your example code is hard to decipher the intention of.
for (int i = 0; i <= Collection.Count && Collection[i].Name != "Alan"; i++)
{
// If name is not Alan, increment i.
}
The for loop has three parts to it, separated by two semi-colons. The first part initializes the loop variable(s). The second part is an expression that is evaluated each time an iteration is about to start; if it is false, the loop terminates. The third part executes after each iteration.
So your loop above will exit at the first "Alan" it encounters, and also it will increment i every time it finishes an iteration. Finally, if there are no Alans, it will execute the last time with i equal to Collection.Count, which is one larger than the maximum valid index into the collection. So it will throw an exception for sure, as you try to access Collection[i] when i is out of range.
Maybe you want this:
foreach (var item in Collection.Where(i => i.Name != "Alan"))
{
// item is not an "Alan"
}
You can think of the Where extension method as a way of filtering a collection.
If this seems obscure, you can achieve the same thing with the continue keyword (as you guessed):
foreach (var item in Collection)
{
if (item.Name == "Alan")
continue;
// item is not an "Alan"
}
Or you can just put the code in the if's block:
foreach (var item in Collection)
{
if (item.Name != "Alan")
{
// item is not an "Alan"
}
}
Do you mean like this?
for (int i = 0; i < 100; ) {
if (!condition1) {
i++;
}
if (!condition2) {
i++;
}
if (!condition3) {
i++;
}
}
Do you want the incrementor for finishing the for loop to be in the body of the loop?
I am not sure I understand correctly. You have a for loop something like this
for (int i = 0; i < 10; i++)
{
// do something
if (!b1)
i++
// do something
}
Edit:
If you use continue it increments i for only once. If you use i++ in loop it increments twice obviously. If you only want to icrement on a condition, Use the for loop like this
for (int i = 0; i < 10) // and this is very similar to a while loop.
From your sample code, I think you are searching for the name "Alan".
Is this correct?
If so, structure your loop like:
for (int i = 0; i < Collection.Count; i++)
{
if (Collection[i].Name == "Alan")
{
break; // We found the name we wanted!
}
// Otherwise: Keep going to look for the name further on.
}
if (i == Collection.Count)
{
Console.WriteLine("Alan is not found");
}
else
{
Console.WriteLine("Alan found at position {0}", i);
}
In the following C# code snippet
I have a 'while' loop inside a 'foreach' loop and I wish to jump to the next item in 'foreach' when a certain condition occurs.
foreach (string objectName in this.ObjectNames)
{
// Line to jump to when this.MoveToNextObject is true.
this.ExecuteSomeCode();
while (this.boolValue)
{
// 'continue' would jump to here.
this.ExecuteSomeMoreCode();
if (this.MoveToNextObject())
{
// What should go here to jump to next object.
}
this.ExecuteEvenMoreCode();
this.boolValue = this.ResumeWhileLoop();
}
this.ExecuteSomeOtherCode();
}
'continue' would jump to the beginning of the 'while' loop not the 'foreach' loop.
Is there's a keyword to use here, or should I just use goto which I don't really like.
Use the break keyword. That will exit the while loop and continue execution outside it. Since you don't have anything after the while, it would loop around to the next item in the foreach loop.
Actually, looking at your example more closely, you actually want to be able to advance the for loop without exiting the while. You can't do this with a foreach loop, but you can break down a foreach loop to what it actually automates. In .NET, a foreach loop is actually rendered as a .GetEnumerator() call on the IEnumerable object (which your this.ObjectNames object is).
The foreach loop is basically this:
IEnumerator enumerator = this.ObjectNames.GetEnumerator();
while (enumerator.MoveNext())
{
string objectName = (string)enumerator.Value;
// your code inside the foreach loop would be here
}
Once you have this structure, you can call enumerator.MoveNext() within your while loop to advance to the next element. So your code would become:
IEnumerator enumerator = this.ObjectNames.GetEnumerator();
while (enumerator.MoveNext())
{
while (this.ResumeWhileLoop())
{
if (this.MoveToNextObject())
{
// advance the loop
if (!enumerator.MoveNext())
// if false, there are no more items, so exit
return;
}
// do your stuff
}
}
The following should do the trick
foreach (string objectName in this.ObjectNames)
{
// Line to jump to when this.MoveToNextObject is true.
this.ExecuteSomeCode();
while (this.boolValue)
{
if (this.MoveToNextObject())
{
// What should go here to jump to next object.
break;
}
}
if (! this.boolValue) continue; // continue foreach
this.ExecuteSomeOtherCode();
}
The break; keyword will exit a loop:
foreach (string objectName in this.ObjectNames)
{
// Line to jump to when this.MoveToNextObject is true.
while (this.boolValue)
{
// 'continue' would jump to here.
if (this.MoveToNextObject())
{
break;
}
this.boolValue = this.ResumeWhileLoop();
}
}
Use goto.
(I guess people will be mad with this response, but I definitely think it's more readable than all other options.)
You can use "break;" to exit the innermost while or foreach.