2009-04-10 16 views
5

Ayer escribí un fragmento de código para eliminar todos los controles en un formulario que cumple ciertos criterios. Escribiéndolo ingenuamente, esto es lo que se me ocurrió.Extracción de controles en un bucle

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

Pero se da la circunstancia de que el código es incorrecto. Luego lo cambio a:

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

Pero todavía no era correcto. Sé que la forma correcta sería:

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

Sin embargo, todavía no se siente elegante. No pude usar List.RemoveAll, ya que this.Controls no era una lista. Entonces, ¿puedo pedir una forma más elegante, preferiblemente sin usar un bucle?

Respuesta

13

No estoy seguro por qué no te gusto esta respuesta ... He resaltado el importante RemoveAt; Sin embargo, como alternativa en .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); 
     } 

(el original)

No se puede Remove dentro foreach - se rompe el iterador. Un enfoque común en este caso es una iteración hacia atrás :

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

Esto evita el "apagado por uno" temas, etc.

+0

parece una buena respuesta a mí. Yo lo voté. –

+0

No fui yo, pero es la respuesta correcta, ¡entonces +1! –