2010-04-13 4 views
3

모든 구성 요소를 반복하고 ISupportsOpen을 구현하는 사람들이 프로젝트를 열 수 있습니다. ,C# 익명 메서드 변수 범위 문제가 IEnumerable <T>

foreach (ISupportsOpen component in something.Site.Container.Components.OfType<ISupportsOpen>()) 
{ 
    MyClass m = new MyClass(); 
    m.Called += new EventHandler(delegate(object sender, EventArgs e) 
    {       
     if (component.CanOpenProject(..)) component.OpenProject(..); 
    }); 

    itemsList.Add(m); 
} 

방법이 해결해야하십시오 익명 메소드가 호출 될 때 문제이며, 다음 구성 요소 변수는 동일한 요소 (는 IEnumerable에서 외부 범위에서 들어오는) 항상? 복사 -

답변

5

그냥 close over the loop variable 그렇지 않은 :

foreach (ISupportsOpen component in 
     something.Site.Container.Components.OfType<ISupportsOpen>()) 
{ 
    ISupportsOpen copy = component; 
    MyClass m = new MyClass(); 
    m.Called += new EventHandler(delegate(object sender, EventArgs e) 
    {       
     if (copy.CanOpenProject(..)) copy.OpenProject(..); 
    }); 

    itemsList.Add(m); 
} 

당신은 루프의 각 반복에 대한 copy 변수의 새로운 "예"를 얻을이 방법은 - 각각의 대리인이 서로 다른 인스턴스를 캡처합니다. 이전에는 모든 대리인이 동일한 변수를 캡처했습니다.

(이것은 어떤면에서는 중복 질문이지만 검색 상대적으로 어려운 문제의 종류, 그래서 많은 시간을 답변 드리겠습니다.)

+0

나는 왜 그냥 궁금 해요 런타임에 인스턴스가 사용 중임을 알 때 메모리에있는 인스턴스를 보유하지 않습니까? 왜 동일한 변수를 캡처하기 전에 대리자가 사용 되었습니까? –

+0

@ PaN1C_Showt1Me : 언어 사양은 하나의 변수로 'foreach'를 정의합니다. 해당 변수가 캡처되므로 사양에 따라 모두 작동합니다. (이것은 실행 시간보다는 언어적인 것입니다.) 자세한 내용은 Eric의 블로그 게시물 (링크)을 참조하십시오. 언어 디자이너가 타임머신을 사용한다면 foreach의 동작을 바꿀 수있을 것이라고 확신합니다. 그러나 지금은 너무 늦었습니다. –