2009-04-10 12 views
5

Ieri ho scritto un pezzo di codice per rimuovere tutti i controlli in un modulo che soddisfa determinati criteri. Scrivendolo in modo ingenuo, questo è ciò che mi viene in mente.Rimozione dei controlli in un loop

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

Ma succede che il codice sia sbagliato. Quindi lo cambio in:

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

Ma non era ancora corretto. So che il modo corretto sarebbe:

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

Tuttavia ancora non si sente elegante. Non ho potuto utilizzare List.RemoveAll, dal momento che questo.Controls non era un elenco. Quindi posso chiedere un modo più elegante, preferibilmente senza usare un ciclo?

risposta

13

Non sono sicuro del motivo per cui questa risposta non mi è piaciuta ... Ho evidenziato l'importante RemoveAt; tuttavia, in alternativa a 3,5 NET/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); 
     } 

(originale)

Non è possibile Remove entro foreach - si rompe l'iteratore. Un approccio comune è quello di iterare all'indietro:

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

questo modo si evita il "off ad uno" problemi, ecc

+0

sembra una buona risposta per me. L'ho svalutato. –

+0

Non ero io, ma è la risposta corretta, quindi +1! –