2010-12-10 17 views
8

Ich habe ein Problem mit einer anonymen Methode innerhalb einer Schleife.Problem mit verschiedenen "Ausführungskontext" einer anonymen Methode innerhalb einer Schleife

Der folgende Code ist nur mein Problem zu veranschaulichen:

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); 
} 

Und wenn ich in die Schaltfläche klicken, wird der Ausgang ist:

Victor Wooten
Victor Wooten
Victor Wooten
Victor Wooten

statt:

Jaco Pastorius
Marcus Miller
Floh
Vicor Wooten

Der Hauptpunkt meines Problems ist die differents Ausführungskontext. Ich weiß, dass mein Beispiel dumm ist.

+0

Jaco Pastorius, Marcus Miller, Floh und Victor Wooten. Eine davon ist nicht wie die anderen .... – jason

+0

4 verschiedene Stile ... aber ich mag sie alle! – Florian

Antwort

12

Dies ist das Problem der erfassten Variablen. Fix it von

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

zu

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

Hier Wechsel ist eine Erklärung des Problems: Closing over loop variable considered harmful. Indem wir die lokale Variable currentItem in den Gültigkeitsbereich der Schleife setzen und diese schließen, erfassen wir nun diese Variable anstelle der Schleifenvariablen.

+0

Sie können auch eine indizierte Schleife verwenden – Falcon

+0

@Falcon: Was wäre der Vorteil der Verwendung einer indizierten Schleife? –

+0

@Cody: Ich vermute Falcon meinte, dass mit einem 'for (int i ...)' die Zeichenfolge innerhalb des Bereichs notwendig wäre ;-) – digEmAll

0

Ihr Problem ist, dass Sie neue Handler in der Schleife erstellen, das ist unnötig und gefährlich.

Sie erstellen auch eine anonyme Methode, die den Wert in der Schleife fest codiert hat. Das ist schlimmer.

0

In allen Fällen ist Jasons Antwort richtig. Es ist ein Problem der variablen Erfassung. Dies wird hauptsächlich in zwei Situationen auftreten. Threading und Anonymous Methoden

Verwandte Themen