2009-04-10 70 views
5

昨天我寫了一段代碼來刪除滿足特定條件的表單中的所有控件。天真地寫,這就是我想出來的。刪除循環中的控件

for (int i = 0; i < this.Controls.Count; ++i) 
{ 
    if (this.Controls[i].Name.Length == 2) 
    { 
     this.Controls.Remove(this.Controls[i); 
    } 
} 

但它碰巧代碼是錯誤的。我然後將其更改爲:

foreach (Control ctr in this.pbBoardImage.Controls) 
{ 
    if (ctr.Length == 2) 
    { 
     this.Controls.Remove(ctr); 
    } 
} 

但它仍然不正確。 我知道正確的方法是:

for (int i = this.Controls.Count - 1; i >= 0; i--) 
{ 
    if (this.Controls[i].Name.Length == 2) 
    { 
     this.Controls.Remove(this.Controls[i]); 
    } 
} 

但它仍然不覺得優雅。我無法使用List.RemoveAll,因爲this.Controls不是List。那麼我可以要求更優雅的方式,最好不使用循環?

回答

13

不知道爲什麼你不喜歡這個答案...我已經強調了重要的RemoveAt;然而,在.NET 3.5的替代/ C#3.0:LINQ:

 var qry = from Control control in Controls 
        where control.Name.Length == 2 
        select control; 

     foreach(var control in qry.ToList()) { 
      Controls.Remove(control); 
     } 

(原件)

您不能Removeforeach - 它打破了迭代器。這裏的一個普遍的方法是迭代向後

for (int i = this.Controls.Count - 1; i >= 0; i--) { 
    if (this.Controls[i].Name.Length == 2) { 
     this.Controls.RemoveAt(i); // <=========== *** RemoveAt 
    } 
} 

這樣就避免了「過一個」問題等

+0

似乎是一個很好的回答了我。我把它提高了。 – 2009-04-10 08:07:29