21

How can I restart a foreach loop in C#??

For example:

Action a;
foreach(Constrain c in Constrains)
{
   if(!c.Allows(a))
   {
      a.Change();
      restart;
   }
}

restart here is like continue or break but it restarts the foreach from the begining It is like setting the counter of a for loop to 0 again..

Is that possible in C#?

Edit:I want to thank both Mehrdad Afshari and Mahesh Velaga for letting me discover a bug (index=0) in my current implementation, that would not have been discovered otherwise..

4

5 回答 5

61

Use the good old goto:

restart:
foreach(Constrain c in Constrains)
{
   if(!c.Allows(a))
   {
      a.Change();
      goto restart;
   }
}

If you're diagnosed with gotophobia 100% of the time for some reason (which is not a good thing without a reason), you can try using a flag instead:

bool restart;
do {
   restart = false;
   foreach(Constrain c in Constrains)
   {
      if(!c.Allows(a))
      {
         a.Change();
         restart = true;
         break;
      }
   }
} while (restart);
于 2011-01-01T12:54:03.260 回答
11

虽然一个非常古老的线程 - 没有一个答案适当注意该代码的语义:

  • 你有一系列的约束a
  • 如果a破坏了其中任何一个,请尝试另一个a并将其推过链条。

也就是a.Change()应该脱离约束检查循环,同样秉承CQS原则:

while (!MeetsConstraints(a))
{
    a.Change();
}

bool MeetsConstraints(Thing a)
{
    return Constraints.All(c => c.Allows(a));
}

没有 goto,没有丑陋的循环,只是简单而干净。</自我拍背>

于 2014-05-27T07:03:15.553 回答
8

One way you can do that is using for, as you have already mentioned:

restart here is like continue or break but it restarts the foreach from the begining It is like setting the counter of a for loop to 0 again

Action a;
for(var index = 0; index < Constratins.Count; index++)
{
   if(!Constraints[index].Allows(a))
   {
      a.Change();
      index = -1; // restart
   }
}
于 2011-01-01T13:04:37.003 回答
4
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;
}
于 2011-01-01T13:04:03.990 回答
0
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
    var c = en.Current;
    if (!c.Allows(a))
    {
        a.Change();
        en = Constrains.GetEnumerator();
    }
}
于 2011-01-01T13:09:13.077 回答