删除循环中的控件

Hao*_*Lim 5 .net c# winforms

昨天我写了一段代码来删除满足特定条件的表单中的所有控件.写得天真,这就是我想出来的.

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

但事实上代码是错误的.然后我将其更改为:

foreach (Control ctr in this.pbBoardImage.Controls)
{
    if (ctr.Length == 2)
    {
        this.Controls.Remove(ctr);
    }
}
Run Code Online (Sandbox Code Playgroud)

但它仍然不正确.我知道正确的方法是:

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

然而,它仍然感觉不优雅.我无法使用List.RemoveAll,因为this.Controls不是List.那么我可以要求更优雅的方式,最好不要使用循环吗?

Mar*_*ell 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);
        }
Run Code Online (Sandbox Code Playgroud)

(原版的)

你不能Removeforeach- 它打破了迭代器.这里常见的方法是向后迭代:

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

这避免了"一个一个"的问题,等等.