Redémarrer une boucle de foreach en C#?
Comment redémarrer une boucle foreach
en C#??
par exemple:
Action a;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart;
}
}
restart
ici c'est comme continue
ou break
mais il redémarre l'avant-bras dès le début
C'est comme remettre le compteur d'une boucle for
à 0..
est-ce possible dans C#?
Edit:je tiens à remercier à la fois Mehrdad Afshari et Mahesh Velaga de m'avoir fait découvrir un bug (index=0) dans ma mise en œuvre actuelle, qui n'aurait pas été découverte autrement..
5 réponses
utiliser le bon vieux goto
:
restart:
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
goto restart;
}
}
si vous êtes diagnostiqué avec la gotophobie 100% du temps pour une raison quelconque (qui est pas une bonne chose sans raison), vous pouvez essayer d'utiliser un drapeau à la place:
bool restart;
do {
restart = false;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart = true;
break;
}
}
} while (restart);
Une façon de le faire est d'utiliser, comme vous l'avez déjà mentionné:
redémarrer ici est comme Continuer ou casser mais il redémarre le foreach de la début C'est comme paramètre le compteur d'une boucle for 0
Action a;
for(var index = 0; index < Constratins.Count; index++)
{
if(!Constraints[index].Allows(a))
{
a.Change();
index = -1; // restart
}
}
bien qu'il s'agisse d'un fil très ancien, aucune des réponses n'a tenu compte de la sémantique de ce code:
- vous avez une chaîne de contraintes sur
a
- si
a
casse l'un d'eux, essayez un autrea
et poussez-le à travers la chaîne.
C'est-à-dire a.Change()
devrait être séparé de la boucle de vérification des contraintes, en adhérant également au principe CQS:
while (!MeetsConstraints(a))
{
a.Change();
}
bool MeetsConstraints(Thing a)
{
return Constraints.All(c => c.Allows(a));
}
Pas de goto, pas de laide de boucles, juste simple et propre.
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;
}
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
var c = en.Current;
if (!c.Allows(a))
{
a.Change();
en = Constrains.GetEnumerator();
}
}