array - foreach list object c#
¿Reiniciar un bucle foreach en C#? (5)
¿Cómo puedo reiniciar un bucle foreach
en C #?
Por ejemplo:
Action a;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart;
}
}
restart
aquí es como continue
o break
pero reinicia el foreach desde el principio. Es como poner de nuevo el contador de un bucle for
en 0.
¿Es eso posible en C #?
Edit: quiero agradecer a Mehrdad Afshari y Mahesh Velaga por permitirme descubrir un error (índice = 0) en mi implementación actual, que de otra forma no se habría descubierto.
Aunque es un hilo muy antiguo, ninguna de las respuestas prestó la debida atención a la semántica de ese código:
- Tienes una cadena de restricciones en
a
- Si se rompe alguno de ellos, pruebe con otro y empuje eso a través de la cadena.
Es decir, a.Change()
debe separar del bucle de verificación de restricciones, también se adhiere al principio de CQS:
while (!MeetsConstraints(a))
{
a.Change();
}
bool MeetsConstraints(Thing a)
{
return Constraints.All(c => c.Allows(a));
}
No goto, no hay bucles feos, simplemente simple y limpio. </self-back-slapping>
Una forma de hacerlo es usando for, como ya ha mencionado:
reiniciar aquí es como continuar o romper, pero reinicia el foreach desde el principio. Es como poner de nuevo el contador de un bucle for en 0.
Action a;
for(var index = 0; index < Constratins.Count; index++)
{
if(!Constraints[index].Allows(a))
{
a.Change();
index = -1; // restart
}
}
Usa el buen viejo goto
:
restart:
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
goto restart;
}
}
Si le diagnostican gotofobia el 100% del tiempo por alguna razón (lo cual no es bueno sin una razón), puede intentar usar una bandera en su lugar:
bool restart;
do {
restart = false;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart = true;
break;
}
}
} while (restart);
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
var c = en.Current;
if (!c.Allows(a))
{
a.Change();
en = Constrains.GetEnumerator();
}
}
void Main()
{
IEnumerable<Constrain> cons;
SomeObject a;
while(!TryChangeList(cons, a)) { }
}
// the name tryChangeList reveals the intent that the list will be changed
private bool TryChangeList(IEnumerable<Constrain> constrains, SomeObject a)
{
foreach(var con in constrains)
{
if(!c.Allows(a))
{
a.Change();
return false;
}
}
return true;
}