簡體   English   中英

在C#中重新啟動foreach循環?

[英]Restart a foreach loop in C#?

如何在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讓我發現我當前實現中的一個錯誤(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);

雖然是一個非常古老的線程 - 沒有一個答案適當注意該代碼的語義:

  • 你有約束的一個鏈a
  • 如果a休息的任何人,嘗試另一種a推,通過鏈條。

也就是說, a.Change()應該與約束檢查循環分開,同時遵循CQS原則:

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

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

沒有goto,沒有丑陋的循環,只是簡單而干凈。 </自背拍打>

正如您已經提到的那樣,您可以使用的一種方法是使用:

這里重新啟動就像繼續或中斷但它從開始重新啟動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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM