para for detener decreciente comando codigo c# .net c#-4.0 .net-4.0

detener - foreach c#



Romper el bucle foreach interno y continuar el bucle foreach externo (8)

Si tengo un bucle foreach anidado, ¿cómo puedo romper el bucle interno y decirle al exterior que continúe en ese punto sin hacer ningún otro código debajo del bucle interno?

foreach(var item in items) { foreach(var otheritem in otheritems) { if (!double.TryParse(otheritem)) { //break inner loop //continue outer loop so we never get to DoStuff() } } DoStuff(); }


¿Qué hay de usar una bandera?

foreach(var item in items) { bool flag = false; foreach(var otheritem in otheritems) { if (!double.TryParse(otheritem)) { flag = true; break; } } if(flag) continue; DoStuff(); }


Comience escribiendo una versión mejorada de Double.TryParse:

static double? TryParseDouble(this string s) { double d; return double.TryParse(s, out d) ? (double?)d : (double?)null; }

Bien, ahora tiene algo que puede usar fácilmente para eliminar por completo el bucle interno, por lo que el problema desaparece:

foreach(var item in items) if (!otheritems.Any(otherItem=>otherItem.TryParseDouble() == null)) DoStuff();

En lugar de tratar de averiguar cómo mover el control, simplemente escriba un código que se parezca a la lógica . Si la lógica es "no hacer cosas si alguno de los otros elementos no se analiza como dobles", utilice el predicado Cualquier para probar todos los demás elementos para ver si alguno de ellos no se analiza como dobles. No hay bucles, por lo que no es necesario un control de bucle elegante

Me gustaría ir un paso más allá; capturar la lógica en una consulta y luego iterar la consulta:

var goodItems = from item in items where !item.OtherItems.Any(otherItem=>otherItem.TryParseDouble() == null)) select item; foreach(var goodItem in goodItems) DoStuff(goodItem);


Iirc un descanso; La instrucción solo romperá el bucle más cercano, por lo que emitir un salto; en el bucle interno debe continuar con el siguiente elemento en el bucle externo.


Necesitas una variable para controlar eso y como dices ... haz un break .

bool doStuff = true; foreach(var item in items) { doStuff = true; foreach(var otheritem in otheritems) { if (!double.TryParse(otheritem)) { doStuff = false; break; } } if (doStuff) DoStuff(); }


No está claro en su fragmento, pero si solo tiene que buscar valores no analizables en otros otheritems , puede usar LINQ:

foreach(var item in items) { bool shouldISkip = otheritems.Any(otherItem => !double.TryParse(otherItem)); if(shouldISkip) continue; DoStuff(); }


Simple es mejor...

bool doStuff = true; foreach(var otheritem in otheritems) { if (!double.TryParse(otheritem)) { doStuff = false; break; } } if(doStuff) DoStuff();

Otro enfoque es refactorizar:

foreach(var outerItem in outerLoop) { Foo(outerItem); } ... void Foo(OuterItem item) { foreach(var innerItem in innerLoop) { if(someTest) return; } DoStuff(); }

La return asegura que el DoStuff no suceda.


foreach(var item in items) { foreach(var otheritem in otheritems) { if (!double.TryParse(otheritem)) { //... goto nextUpperLoop; } } DoStuff(); nextUpperLoop: ; }


foreach(var item in items) { var shouldContinue = false; foreach(var otheritem in otheritems) { if (!double.TryParse(otheritem)) { shouldContinue = true; //break inner loop //continue outer loop so we never get to DoStuff() } } if(shouldContinue) continue; DoStuff(); }