如何在C#中重新启动foreach
循环
例如:
Action a;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart;
}
}
restart
这里就像continue
或break
但它从一开始就重新启动了foreach
这就像将for
循环的计数器再次设置为0 ..
这可能在C#中吗?
编辑:我要感谢Mehrdad Afshari和Mahesh Velaga,让我发现我当前实现中的一个错误(index = 0),否则就不会被发现..
答案 0 :(得分:57)
使用旧的goto
:
restart:
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
goto restart;
}
}
如果您因某种原因100%被诊断出患有恐惧症(这是不是没有理由的好事),您可以尝试使用标志:
bool restart;
do {
restart = false;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart = true;
break;
}
}
} while (restart);
答案 1 :(得分:8)
正如您已经提到的那样,您可以使用的一种方法是使用:
重启这里就像继续或休息一样 但它重新启动了foreach 开始就像将for循环的计数器再次设置为0
Action a;
for(var index = 0; index < Constratins.Count; index++)
{
if(!Constraints[index].Allows(a))
{
a.Change();
index = -1; // restart
}
}
答案 2 :(得分:8)
虽然是一个非常老的线程 - 没有一个答案适当注意该代码的语义:
a
a
打破其中任何一个,请尝试另一个a
并将其推入链中。也就是说,a.Change()
应该与约束检查循环分开,同时遵守CQS原则:
while (!MeetsConstraints(a))
{
a.Change();
}
bool MeetsConstraints(Thing a)
{
return Constraints.All(c => c.Allows(a));
}
没有转到,没有丑陋的循环,只是简单而干净。 &LT; /自背拍打&GT;
答案 3 :(得分: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;
}
答案 4 :(得分:0)
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
var c = en.Current;
if (!c.Allows(a))
{
a.Change();
en = Constrains.GetEnumerator();
}
}