Restart a foreach loop in C#?

前端 未结 5 1222
傲寒
傲寒 2021-02-07 04:02

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

For example:

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


        
相关标签:
5条回答
  • 2021-02-07 04:08
    for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
    {
        var c = en.Current;
        if (!c.Allows(a))
        {
            a.Change();
            en = Constrains.GetEnumerator();
        }
    }
    
    0 讨论(0)
  • 2021-02-07 04:10

    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);
    
    0 讨论(0)
  • 2021-02-07 04:22
    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;
    }
    
    0 讨论(0)
  • 2021-02-07 04:23

    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
       }
    }
    
    0 讨论(0)
  • 2021-02-07 04:29

    Although a very old thread - none of the answers paid due attention to the semantics of that code:

    • You have a chain of constraints on a
    • If a breaks any of them, try another a and push that through the chain.

    That is, a.Change() should be separated from the constraint checking loop, also adhering to the CQS principle:

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

    No goto, no ugly loops, just simple and clean. </self-back-slapping>

    0 讨论(0)
提交回复
热议问题