[英]Restart a foreach loop in C#?
How can I restart a foreach
loop in C#?? 如何在C#中重启foreach
循环?
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.. 在这里restart
就像continue
或break
但它从开始重新启动foreach就像将for
循环的计数器再次设置为0一样。
Is that possible in C#? 这可能在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.. 编辑:我要感谢Mehrdad Afshari和Mahesh Velaga让我发现我当前实现中的一个错误(index = 0),否则就不会发现它。
Use the good old goto
: 使用好旧的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: 如果你出于某种原因100%被诊断出患有恐惧症(这是没有理由的好事),你可以尝试使用标志代替:
bool restart;
do {
restart = false;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart = true;
break;
}
}
} while (restart);
Although a very old thread - none of the answers paid due attention to the semantics of that code: 虽然是一个非常古老的线程 - 没有一个答案适当注意该代码的语义:
a
你有约束的一个链a
a
breaks any of them, try another a
and push that through the chain. 如果a
休息的任何人,尝试另一种a
推,通过链条。 That is, a.Change()
should be separated from the constraint checking loop, also adhering to the CQS principle: 也就是说, a.Change()
应该与约束检查循环分开,同时遵循CQS原则:
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. 没有goto,没有丑陋的循环,只是简单而干净。 </self-back-slapping> </自背拍打>
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 这里重新启动就像继续或中断但它从开始重新启动foreach 就像再次将for循环的计数器设置为0
Action a;
for(var index = 0; index < Constratins.Count; index++)
{
if(!Constraints[index].Allows(a))
{
a.Change();
index = -1; // restart
}
}
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;
}
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
var c = en.Current;
if (!c.Allows(a))
{
a.Change();
en = Constrains.GetEnumerator();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.