2010-12-10 8 views
8

Tengo un problema con un método anónimo dentro de un bucle.Problema con diferente "contexto de ejecución" de un método anónimo dentro de un bucle

El código siguiente es sólo para ilustrar mi problema:

private void Form1_Load(object sender, EventArgs e) 
{ 
    List<string> bassists = new List<string>(){ 
     "Jaco Pastorius", 
     "Marcus Miller", 
     "Flea", 
     "Vicor Wooten" 
    }; 

    foreach (string item in bassists) 
    { 
     this.button1.Click += (s, ea) => Output(s, ea, item); 
    } 
} 

private void Output(object s, EventArgs e, string item) 
{ 
    this.listBox1.Items.Add(item); 
} 

Y cuando hago clic en el botón, la salida es:

Victor Wooten
Victor Wooten
Victor Wooten
Victor Wooten

en lugar de:

Jaco Pastorius
Marcus Miller
Pulga
Vicor Wooten

El punto principal de mi problema es el contexto de ejecución de los differents. Sé que mi ejemplo es estúpido.

+0

Jaco Pastorius, Marcus Miller, Flea y Victor Wooten. Uno de estos no es como los otros ... – jason

+0

4 estilos diferentes ... ¡pero me gustan todos! – Florian

Respuesta

12

Este es el problema de variable capturada. Solucionarlo cambiando

foreach (string item in bassists) 
{ 
    this.button1.Click += (s, ea) => Output(s, ea, item); 
} 

a

foreach (string item in bassists) 
{ 
    string currentItem = item; 
    this.button1.Click += (s, ea) => Output(s, ea, currentItem); 
} 

He aquí una explicación de la cuestión: Closing over loop variable considered harmful. Al poner la variable local currentItem en el alcance del ciclo y cerrarlo, ahora capturamos esa variable en lugar de la variable de ciclo.

+0

También puede usar un bucle indexado – Falcon

+0

@Falcon: ¿Cuál sería la ventaja de usar un bucle indexado? –

+0

@Cody: supongo que Falcon quería decir que usando un 'for (int i ...)' la cadena sería necesaria dentro del alcance ;-) – digEmAll

0

Su problema es que está creando nuevos manejadores en el ciclo, eso es innecesario y peligroso.

También está creando un método anónimo que tiene el valor en el bucle codificado. Eso es peor

0

En cualquier caso, la respuesta de Jason es correcta. Es un problema de captura variable. Esto ocurrirá principalmente en dos situaciones Enhebrado y métodos anónimos

Cuestiones relacionadas