Break inside switch Cannot Terminate FOR Loop [duplicate] - c#

This question already has answers here:
Break out of a while loop that contains a switch statement
(15 answers)
Closed 9 years ago.
I have a code snippet :
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
break;
break;//This is unreachable and so i cannot Terminate the For Loop within the SWITCH
}
}
As described in a comment I cannot terminate the For Loop directly from the Switch, only if I declare a boolean and at the End of Switch test
if(LoopShouldTerminate)
break;
PS : or maybe I'm very confused!
[POST]
I got the message ,and the problem is Solved ,but i would like to asume that using Switch within a for loop isn't a god idea ,because i heard from lot of developer's i should break from loop in the moment when i get the desired result ,so using switch need's extra boolean or push the Int i value to 50 direclty , but what would happen if we're using while loop ?

Solution 1: Move the loop and the switch to different methods:
for(int i = 0; i < 50; ++i)
{
if (DoCheckStatus(i)) break;
}
...
bool DoCheckStatus(int i)
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
}
Solution 2: Adapt the above to eliminate the loop with an eager extension method:
static void DoWhile<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
foreach(T item in sequence)
if (!predicate(item)) return;
}
...
Enumerable.Range(0, 50).DoWhile(DoCheckStatus)
Solution 3: Adapt the above to eliminate the loop and the helper method:
Enumerable.Range(0, 50).DoWhile(i=>
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
});

You can use goto in order to break out of the loop within the switch.
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
goto outofloop;
}
}
:outofloop
// more code
One of the few good uses of goto...

Just change the value of i:
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
i += 50;
break;
}
}

If there is no other code after the switch you can just check in the for loop itself whether to continue looping:
bool doContinue = true;
for (int i = 0; i < 50 && doContinue; i++)
{
n = checkStatus();
switch (n)
{
case 1:
doContinue = false;
}
}

Can you place the loop inside of a method and just use return?
Example:
myLoopingMethod()
{
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
return;
}
}
}
Another option would be to use a traditional if/else instead of a switch/case. Then you can just use break and it will jump out of your for loop

You could use a boolean.
int n = 0;
for (int i = 0; i < 50; i++)
{
bool shouldBreak = false;
n = checkStatus();
switch (n)
{
case 1:
shouldBreak = true;
break;
}
if (shouldBreak)
break;
}

I don't know if there's other logic that needs to be performed after the loop is finished, but you could try using return instead. The other option is to set a boolean flag, and exit after the switch.
switch (n)
{
case 1:
return;
}

This smells of bad design; there are a couple of ways you could fix this:
If only one condition of your switch would break the outer loop, then simply check for that before entering the switch:
if(n == 1)
break;
switch(n) { }
If multiple conditions can break the loop, refactor to a more linq style query:
Enumerable.Range(0, 50).FirstOrDefault(x => listOfBreakCodes.Contains(checkStatus());
That should call checkStatus up to 50 times until it encounters a 1 (or other break codes), and then doesnt continue evaluating elements.

Related

switch while won't loop

This is part of a program I'm writting. My main porblem is that once it goes trough one of the cases, tit won't loop so it's useless as it is. Any help? (Sorry for the variables in Spanish, also a couple of functions i created appear in the cose which are in the program and work just fine so I don't thin they have anything to do with the problem).
static void Main(string[] args)
{
int minutos_restantes = 480;
int opcion;
int valorComercial = 0;
Tarea[] listado_tareas = new Tarea[10];
CrearTareas(ref listado_tareas);
Console.WriteLine("1. Mostrar tareas. \n2. Asignar tarea \n3. Salir, \n Elige opción: ");
opcion = Convert.ToInt32(Console.ReadLine());
switch (opcion)
{
case 1:
Imprimirtareas(listado_tareas);
break;
case 2:
Console.WriteLine("Seleccionar número de tarea: ");
int n = Convert.ToInt32(Console.ReadLine())-1;
if (n < 0 || n > 10)
{
Console.WriteLine("TAREA INEXISTENTE");
}
else if (listado_tareas[n].realizada == true)
{
Console.WriteLine("TAREA YA REALIZADA");
}
else if((minutos_restantes - listado_tareas[n].tiempo) <= 0)
{
Console.WriteLine("TIEMPO INSUFICIENTE");
}
else
{
listado_tareas[n].realizada = true;
minutos_restantes -= listado_tareas[n].tiempo;
}
break;
} while (opcion != 3) ;
}
I don't think you can loop over a switch like this.
Try doing the while separate:
do
{
switch (opcion)
{
case 1:
Imprimirtareas(listado_tareas);
break;
case 2:
Console.WriteLine("Seleccionar número de tarea: ");
int n = Convert.ToInt32(Console.ReadLine())-1;
if (n < 0 || n > 10)
{
Console.WriteLine("TAREA INEXISTENTE");
}
else if (listado_tareas[n].realizada == true)
{
Console.WriteLine("TAREA YA REALIZADA");
}
else if((minutos_restantes - listado_tareas[n].tiempo) <= 0)
{
Console.WriteLine("TIEMPO INSUFICIENTE");
}
else
{
listado_tareas[n].realizada = true;
minutos_restantes -= listado_tareas[n].tiempo;
}
break;
}
}while (opcion != 3) ;
There's no such construct:
switch
{
} while (...);
In C#. What you've actually written is:
switch
{
}
while (...);
Which is another way of writing
switch
{
}
while (...)
{
}
I suspect you want to put your switch statement inside a while or a do...while loop.
Go for something like this:
int opcion = 0;
do
{
opcion = Convert.ToInt32(Console.ReadLine());
switch (opcion)
{
...
}
} while (opcion != 3);
Check this one too: While Loop in C# with Switch Statement
This is broken code.
You have a switch() {} statement (without default and those breaks cause you to fall out of its scope) and a while (condition) /*do nothing*/; statement.
The intention is do{switch(){}}while() ?
Time to do some reading...
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/while
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/do
You should do :-
while (condition)
{
switch
{
}
}

Break for loop statement with nested switch

I'm trying to break a forloop using break as traditional, but in this case I find myself stuck with this nested switch where the break only works into the switch scope and the loop keeps iterating.
for (int i = 0; i < lenght; i++)
{
switch (enum)
{
case Enum.some_1: break;
case Enum.some_2: break;
case Enum.some_3: break;
}
}
There are multiple options to approach this:
Using helper variable
bool exit = false;
for (int i = 0; i < length && !exit; i++)
{
switch(enum)
{
case Enum.case_which_breaks:
exit = true;
break;
// other cases
}
// some other code, which may use `i`
}
Using helper method
This would be simpler, if you could refactor out the whole for block into a helper method. In this case, you'll use return rather than break.
private Result HandleInternally(int length, Enum enum, Request params)
{
for (int i = 0; i < length; i++)
switch (enum)
{
case Enum.case_which_breaks:
Result result = new Result(); //populate the result
return result;
// other cases
}
}
And then in the consuming code simply call the method.
bool exitForLoop = false;
for (int i = 0; i < length && !exitForLoop; i++)
{
switch (enum)
{
case Enum.some_1: exitForLoop = true; break;
case Enum.some_2: break;
case Enum.some_3: break;
}
}
bool exit = false;
int i = 0;
while (!exit && i < length)
{
switch (enum)
{
case Enum.some_1: exit = true; break;
case Enum.some_2: exit = true; break;
case Enum.some_3: exit = true; break;
}
i++;
}

How to make "for" with stop?

This is my code:
switch(gift1)
{
case 1:
for (int ik = 0; allbuild[ik] == g[1]; ik++)
{
if (allbuild[ik] == 0)
allbuild[ik] = g[1];
}
break;
case 2:
for (int ik = 0; allbuild[ik] == g[2]; ik++)
{
if (allbuild[ik] == 0)
allbuild[ik] = g[2];
}
break;
}
I want this:
if allbuild[ik] == 0, then it gets value from g[1] or g[2] and "for" ends, but it's doesnt works like I want. allbuild gets value for all items.
allbuild[1] = g[1];
allbuild[2] = g[2];
allbuild[3] = g[3];
and so on, to albuild[100].
Use break;, which jumps to the end of innermost for loop.
For example:
for (int ik = 0; allbuild[ik] == g[1]; ik++)
{
if (allbuild[ik] == 0)
{
... do what it is that you want to do ...
break;
}
}
First, I doubt whether for loop conditions i.e. allbuild[ik] == g[2] and alike are valid; probably you want to test (potentially) all the items.
Next the copy-pasted switch with 100 brunches looks really ugly, let's cram it into the loop:
//TODO: check loop condition
for (int ik = 0; allbuild[ik] == g[gift1]; ik++)
if (allbuild[ik] == 0) {
allbuild[ik] = g[gift1];
break; // <- break the "for loop"
}
It's unclear what you're asking. for loops run on conditions specified in the initial part:
"int ik = 0; allbuild[ik] == g[1]; ik++"
where
allbuild[ik] == g[1]
is the condition it is evaluating. If that no longer holds true, then it will stop iterating. You can do a lot of things to make this evaluate to false.
However, you can also escape your for loop using a lot of other mechanism:
use the break statement to stop the for loop entirely, and continue on the next statement.
use a continue statement to skip the rest of the current iteration of the loop
use a return statement to get out of the current method
use a goto statement (highly unrecommended)
throw an Exception
use an exit code eg. Environment.Exit(code) statement
I suggest you read up on for loops and debug your code line by line. This is applicable in all languages.
The reason you don't get what you're expecting is that at the end of the block ik gets incremented so that exit condition is comparing the next value in allbuild[] with g[1].
Correct usage of break would be:
switch(gift1)
{
case 1:
{
for (int ik = 0; allbuild[ik] == g[1]; ik++)
{
if (allbuild[ik] == 0)
{
allbuild[ik] = g[1];
break;
}
}
break;
}
case 2:
{
for (int ik = 0; allbuild[ik] == g[2]; ik++)
{
if (allbuild[ik] == 0)
{
allbuild[ik] = g[2];
break;
}
}
break;
}
}
Actually it looks like you are looking for this code:
if (/*condition you need is unclear, according to your code it is: allbuild[0] != g[gift1]*/)
{
for (int ik = 0; ik < allbuild.Length; ik++)
{
if (allbuild[ik] == 0)
{
allbuild[ik] = g[gift1];
break;
}
}
}

Using a for loop inside switch/case

Can I use a for loop inside a switch/case?
Example code:
String[,] drinks = new String[,] { { "Cola", "20" }, { "Fanta", "20" }, { "Sprite", "20" }, { "Tuborg", "25" }, { "Carlsberg", "25" } };
switch (menuChoice)
{
case 0:
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
break;
for (int i = 0; i < drinksCount; i++)
{
case i+1:
buyDrink(drinks[i,0];
break;
}
(More code and methods is in between these)
Basically, I create an array with the drinks this machine sells, and then I want to create a menu where to chose these drinks, but also the ability to add more drinks within the GUI.
Is this even possible?
You can use loops inside switch statement but not the way you are using it currently. Try to replace your code with below code:
if (menuChoice == 0)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else if (menuChoice > 0 && menuChoice < drinksCount)
{
buyDrink(drinks[menuChoice, 0]);
}
ADDED:
As per valuable comments, why don't you just use -1 as menuChoice for Exit, this way:
if (menuChoice == -1)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else if (menuChoice > 0 && menuChoice <= drinksCount)
{
buyDrink(drinks[menuChoice - 1, 0], Convert.ToDouble(drinks[menuChoice - 1, 1]));
}
This way you can call your static method as shown:
static void buyDrink(String drink, double drinkPrice)
A better title for this question might be: Is it possible to have variable case statements?
case i+1:
This is an invalid case statement. A the value of a case statement must be a constant. If i were a constant in this case, it would be allowed. However, i isn't, and therefore the case statement will not compile.
Having said that, although the answer to the title question is yes, as shown by other answers, the real answer here is: Not the way you're trying to do it.
It doesn't make sense to have code after break.
You break from the case how do you expect it to execute?
case 0:
{
break;//If you break here, it exits the block.. your loop never executes
for (int i = 0; i < drinksCount; i++)
{
case i+1:
buyDrink(drinks[i,0];
break;
}
}
And even if it is possible I fail to see the point.
You will execute the case as long as it is greater than 0 right?
So why not just use an if statement, help yourself and others?
if(menuChoice ==0)
{
//dosomething
}
else if(menuChoice >0)
{
//buy drink
}
if(menuChoice == 0) {
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
} else if(menuChoice > 0 && menuChoice <= drinksCount) {
buyDrink(drinks[menuChoice - 1, 0]);
}
That code could not work at all.
A break is the final (and required) statement of a case.
Looking at your example you could simply write
if(menuChoice == 0)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else
{
buyDrink(drinks[menuChoice-1,0]);
}
EDIT: Seeing your comment about buyDrink as static method and the parameters required then you should change the call to buyDrink prepending the class name where the buyDrink method is defined and add the parameter for the price (as double value)
.......
else
{
BeverageClass.buyDrink(drinks[menuChoice-1,0], Convert.ToDouble(drinks[menuChoice-1,1]));
}

Break foreach loop (WCF server/client)

I have a simple code, which send from server to clients value to count. This loop count for 9 value, from 1 to 9. Everything work good for 1,3 or 9 clients. But for other number of clients when i_wiersz has value 9 and foreach loop want sent something to another client server break down. Ho make, to work with any one numbers of clients?
I try put inside foreach loop:
if(i_wiersz == 9)
break;
but a get an error: Error
Control cannot leave the body of an anonymous method or lambda
expression
My code:
bool spr_wiersz(int wiersz, int kolumna) //chck_roow(int roow, int column)
{
wys_tab();
int i_wiersz = 0;
bool[] result = new bool[9];
while (i_wiersz < 9)
{
subscribers.ForEach(delegate(ImessageCallback callback)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
result[i_wiersz] = callback.spr_wiersz(wiersz, kolumna, i_wiersz);
i_wiersz++;
}
});
for (int j = 0; j < i_wiersz; j++)
{
if (result[j] == false)
{
return false;
}
}
}
return true;
}
Can’t you simply convert it to a traditional foreach?
foreach (IMessageCallback callback in subscribers)
{
if (((ICommunicationObject)callback).State == CommunicationState.Opened)
{
result[i_wiersz] = callback.spr_wiersz(wiersz, kolumna, i_wiersz);
i_wiersz++;
if (i_wiersz == 9)
break;
}
}

Categories

Resources