2010-12-10 14 views
8

Mam problem z anonimową metodą w pętli.Problem z innym "kontekstem wykonania" anonimowej metody w pętli

Poniższy kod jest tylko do zilustrowania mój problem:

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

A kiedy kliknij w przycisk, wyjście jest:

Victor Wooten
Victor Wooten
Victor Wooten
Victor Wooten

zamiast:

Jaco Pastorius
Marcus Miller
Flea
Vicor Wooten

Głównym punktem mojego problemu jest wykonanie zróżnicowanych kontekst. Wiem, że mój przykład jest głupi.

+0

Jaco Pastorius, Marcus Miller, Flea and Victor Wooten. Jeden z nich nie jest taki jak inne ... – jason

+0

4 różne style ... ale lubię je wszystkie! – Florian

Odpowiedz

12

To jest problem z przechwytywaną zmienną. Napraw to zmieniając

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

do

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

Oto wyjaśnienie kwestii: Closing over loop variable considered harmful. Umieszczając zmienną lokalną currentItem w zasięgu pętli i zamykając ją, przechwytujemy teraz tę zmienną zamiast zmiennej pętli.

+0

Można również użyć indeksowanej pętli – Falcon

+0

@Falcon: Jaka byłaby korzyść z używania indeksowanej pętli? –

+0

@Cody: Sądzę, że Falcon miał na myśli to, że używając 'for (int i ...)' string będzie potrzebny wewnątrz zakresu ;-) – digEmAll

0

Twój problem polega na tym, że tworzysz nowe pętle w pętli, które są niepotrzebne i niebezpieczne.

Również tworzysz anonimową metodę, która ma zakodowaną wartość w pętli. To jest gorsze.

0

W każdym przypadku odpowiedź Jasona jest prawidłowa. Jest to problem przechwytywania zmiennych. Będzie to w większości przypadków występować w dwóch sytuacjach Metody gwintowania i Anonymous

Powiązane problemy