2010-12-10 7 views
8

Bir döngü içinde anonim bir yöntemle ilgili bir sorunum var.Bir döngü içinde anonim bir yöntemin farklı "yürütme içeriği" ile ilgili sorun

Aşağıdaki kod sadece göstermek için benim 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); 
} 

Ve düğmeye tıkladığınızda, çıktıdır:

Victor Wooten
Victor Wooten

Victor Wooten Victor Wooten

yerine:

Jaco Pastorius
Marcus Miller
Bit
Vicor Wooten

zaman sorun ana noktası değişik yürütme içeriğidir. Benim örneğimin aptalca olduğunu biliyorum.

+0

Jaco Pastorius, Marcus Miller, Flea ve Victor Wooten'de ortaya çıkacaktır. Bunlardan biri diğerleri gibi değil .... – jason

+0

4 farklı stil ... ama hepsini seviyorum! – Florian

cevap

12

Yakalanan değişken problemi budur.

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

için

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

değiştirerek Fix it Burada konunun açıklaması aşağıda verilmektedir: Closing over loop variable considered harmful. Yerel değişken currentItem döngüsüne girerek ve bunun üzerine geçerek, şimdi bu değişkeni döngü değişkeni yerine yakalarız.

+0

Ayrıca, dizinlenmiş bir döngü kullanabilirsiniz – Falcon

+0

@Falcon: Dizine eklenmiş bir döngü kullanmanın avantajı ne olurdu? –

+0

@Cody: Sanırım Falcon, bir 'for (int i ...)' nin kullanılmasının, Lippert'in mükemmel açıklamasının bağlantısı için ;-) – digEmAll

0

Sorununuz, döngüde yeni işleyiciler oluşturduğunuz, bu gereksiz ve tehlikeli olduğudur.

Ayrıca, döngüde kodlanmış değeri olan anonim bir yöntem oluşturuyorsunuz. Bu daha kötü.

0

Jason'ın cevabı her durumda doğrudur. Değişken yakalama problemidir. Bu, büyük ölçüde, iki durum halinde, Threading ve Anonymous (Anonim) metotlarında,

İlgili konular