21

foreachC#でループを再開するにはどうすればよいですか?

例えば:

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

restartこれはまたはのようなものcontinueですbreakが、foreachを最初から再開しforます。ループのカウンターを再び0に設定するようなものです。

それはC#で可能ですか?

編集:MehrdadAfshariとMahesh Velagaの両方に、他の方法では発見されなかったであろう現在の実装のバグ(index = 0)を発見させてくれたことに感謝したいと思います。

4

5 に答える 5

61

古き良きものを使用してください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);
于 2011-01-01T12:54:03.260 に答える
11

非常に古いスレッドですが、そのコードのセマンティクスに十分な注意を払った回答はありませんでした。

  • 一連の制約がありますa
  • aそれらのいずれかが壊れた場合は、別の方法を試しaて、チェーンにプッシュしてください。

つまりa.Change()、制約チェックループから分離し、CQSの原則にも準拠する必要があります。

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

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

後藤も醜いループもありません。シンプルでクリーンです。</セルフバックスラップ>

于 2014-05-27T07:03:15.553 に答える
8

すでに述べたように、それを行う1つの方法はforを使用することです。

ここでの再起動は、続行または中断のようなものですが、foreachを最初から再起動します。これは、forループのカウンターを再び0に設定するようなものです。

Action a;
for(var index = 0; index < Constratins.Count; index++)
{
   if(!Constraints[index].Allows(a))
   {
      a.Change();
      index = -1; // restart
   }
}
于 2011-01-01T13:04:37.003 に答える
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;
}
于 2011-01-01T13:04:03.990 に答える
0
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
    var c = en.Current;
    if (!c.Allows(a))
    {
        a.Change();
        en = Constrains.GetEnumerator();
    }
}
于 2011-01-01T13:09:13.077 に答える