在C#中重新启动foreach循环?
如何在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),否则就不会发现它。
使用好旧的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);
正如您已经提到的那样,您可以使用的一种方法是使用:
这里重新启动就像继续或中断但它从开始重新启动foreach 就像再次将for循环的计数器设置为0
Action a; for(var index = 0; index < Constratins.Count; index++) { if(!Constraints[index].Allows(a)) { a.Change(); index = -1; // restart } }
虽然是一个非常古老的线程 – 没有一个答案适当注意该代码的语义:
- 你有一系列约束条件
- 如果
a
打破其中任何一个,请尝试另一个并将其推入链中。
也就是说, a.Change()
应该与约束检查循环分开,同时遵守CQS原则:
while (!MeetsConstraints(a)) { a.Change(); } bool MeetsConstraints(Thing a) { return Constraints.All(c => c.Allows(a)); }
没有转到,没有丑陋的循环,只是简单而干净。 自背拍打>
void Main() { IEnumerable cons; SomeObject a; while(!TryChangeList(cons, a)) { } } // the name tryChangeList reveals the intent that the list will be changed private bool TryChangeList(IEnumerable 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(); } }