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..

17
demandé sur chiccodoro 2011-01-01 15:53:04

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);
53
répondu Mehrdad Afshari 2011-01-01 12:54:03

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
   }
}
8
répondu Mahesh Velaga 2011-01-01 13:13:36

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 autre a 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.

8
répondu chiccodoro 2014-08-22 10:26:32
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;
}
4
répondu Unmesh Kondolikar 2011-01-01 13:19:41
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
    var c = en.Current;
    if (!c.Allows(a))
    {
        a.Change();
        en = Constrains.GetEnumerator();
    }
}
0
répondu Eivind T 2011-01-01 13:09:13