在C#中重新启动foreach循环?

Bet*_*moo 18 c# foreach loops reserved-words

如何foreach在C#中重启循环?

例如:

Action a;
foreach(Constrain c in Constrains)
{
   if(!c.Allows(a))
   {
      a.Change();
      restart;
   }
}
Run Code Online (Sandbox Code Playgroud)

restart这里是continue或者break它从开始重新启动foreach它就像将for循环的计数器再次设置为0.

这可能在C#中吗?

编辑:我要感谢Mehrdad Afshari和Mahesh Velaga让我发现我当前实现中的一个错误(index = 0),否则就不会发现它.

Meh*_*ari 59

使用好老goto:

restart:
foreach(Constrain c in Constrains)
{
   if(!c.Allows(a))
   {
      a.Change();
      goto restart;
   }
}
Run Code Online (Sandbox Code Playgroud)

如果你出于某种原因100%被诊断出患有恐惧症(这是没有理由的好事),你可以尝试使用标志代替:

bool restart;
do {
   restart = false;
   foreach(Constrain c in Constrains)
   {
      if(!c.Allows(a))
      {
         a.Change();
         restart = true;
         break;
      }
   }
} while (restart);
Run Code Online (Sandbox Code Playgroud)


chi*_*oro 10

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

  • 你有一系列限制 a
  • 如果a打破其中任何一个,请尝试另一个a并将其推入链中.

也就是说,a.Change()应该与约束检查循环分开,也遵循CQS原则:

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

bool MeetsConstraints(Thing a)
{
    return Constraints.All(c => c.Allows(a));
}
Run Code Online (Sandbox Code Playgroud)

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


Mah*_*aga 8

正如您已经提到的那样,您可以使用的一种方法是使用:

这里重新启动就像继续或中断但它从开始重新启动foreach 就像再次将for循环的计数器设置为0

Action a;
for(var index = 0; index < Constratins.Count; index++)
{
   if(!Constraints[index].Allows(a))
   {
      a.Change();
      index = -1; // restart
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是错的.`index = -1`可以工作,如果可枚举是索引可访问的,但即便在这种情况下,它使代码难以阅读并使意图不清楚.这是因为盲目的恐惧症而使事情变得更糟的一个完美的例子.至少,使用`goto`,意图非常明确. (7认同)
  • @Chuck:也许是因为并非所有的集合都可以被索引访问? (5认同)