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

发布于 2024-10-10 02:36:11 字数 429 浏览 0 评论 0原文

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

例如:

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

这里的restart类似于continuebreak,但它从头开始重新启动foreach 这就像再次将 for 循环的计数器设置为 0..

这在 C# 中可能吗?

编辑:我要感谢 Mehrdad Afshari 和 Mahesh Velaga 让我在当前的实现中发现一个错误(索引 = 0),否则不会发现这个错误。

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

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..

Is that possible in 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..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

好听的两个字的网名 2024-10-17 02:36:11

使用古老的goto

restart:
foreach(Constrain c in Constrains)
{
   if(!c.Allows(a))
   {
      a.Change();
      goto restart;
   }
}

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

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

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);
撧情箌佬 2024-10-17 02:36:11

尽管是一个非常古老的线程 - 没有一个答案对该代码的语义给予应有的关注:

  • 您对 a 有一系列约束
  • 如果 a 破坏了其中任何一个,请尝试另一个 a 并将其推入链中。

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

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

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

没有 goto,没有难看的循环,只是简单干净。

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>

苏辞 2024-10-17 02:36:11

正如您已经提到的,您可以做到这一点的一种方法是使用 for :

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

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

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
beginning It is like setting the counter of a for loop to 0 again

Action a;
for(var index = 0; index < Constraints.Count; index++)
{
   if(!Constraints[index].Allows(a))
   {
      a.Change();
      index = -1; // restart
   }
}
早乙女 2024-10-17 02:36:11
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;
}
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;
}
童话 2024-10-17 02:36:11
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
    var c = en.Current;
    if (!c.Allows(a))
    {
        a.Change();
        en = Constrains.GetEnumerator();
    }
}
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
    var c = en.Current;
    if (!c.Allows(a))
    {
        a.Change();
        en = Constrains.GetEnumerator();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文