2010-12-10 3 views
8

루프 내에서 익명 메소드에 문제가 있습니다.루프 내에서 익명 메소드의 다른 "실행 컨텍스트"에 문제가 있습니다.

다음 코드는 설명하기 위해 내 문제 :

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

그리고 버튼으로 클릭 할 때, 출력은 다음과 같습니다

빅터 우튼
빅터 우튼

빅터 우튼 Victor Wooten

대신 :

자코 파스토리우스
마커스 밀러
벼룩
Vicor의 우튼은

내 문제의 주요 포인트는 differents의 실행 컨텍스트입니다. 내 예가 어리 석다는 것을 압니다.

+0

Jaco Pastorius, Marcus Miller, Flea and Victor Wooten. 이것들 중의 1 개는 다른 것과 같지 않다. ... – jason

+0

4 개의 다른 스타일. .. 그러나 나는 그들을 완전히 좋아한다! – Florian

답변

12

이것은 캡처 된 변수 문제입니다.

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

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

을 변경하여 수정 다음 문제에 대한 설명은 다음과 같습니다 Closing over loop variable considered harmful. 로컬 변수 currentItem을 루프의 범위에 넣고 닫으면 루프 변수 대신 해당 변수를 캡처합니다.

+0

인덱스 된 루프를 사용할 수도 있습니다. – Falcon

+0

@Falcon : 인덱스 된 루프를 사용하면 어떤 이점이 있습니까? –

+0

@Cody : 팔콘은 Lippert의 뛰어난 설명에 대한 링크를 위해서 – digEmAll

0

문제는 루프에 새 처리기를 작성하는 것이므로 불필요하고 위험합니다.

또한 루프의 값이 하드 코딩 된 익명 메소드를 만듭니다. 그것은 더 나쁘다.

0

제이슨의 답변이 어떤 경우이든간에. 변수 캡쳐의 문제입니다. 이것은 주로 스레딩과 익명의 두 가지 상황에서 발생합니다

관련 문제