2010-11-24 4 views
0

다음 프로그램이 경우 이벤트가 다르게 작동하는 이유는 무엇입니까?

static IEnumerable<Action> Create() 
{ 
    foreach (var i in Enumerable.Range(0, 2)) 
    { 
     yield return() => { Console.Write(i); }; 
    } 
} 

static void Main(string[] args) 
{ 
    foreach (var func in Create()) 
    { 
     func(); 
    } 

    Console.ReadLine(); 
} 

으로 출력한다

01

이 프로그램

static event Action SomethingHappened; 

static void Register() 
{ 
    foreach (var i in Enumerable.Range(0, 2)) 
    { 
     SomethingHappened +=() => { Console.Write(i); }; 
    } 
} 

static void Main(string[] args) 
{ 
    Register(); 
    SomethingHappened(); 
    Console.ReadLine(); 
} 

출력

왜 그렇습니까? 프로그램 2 출력을 만드는 방법 01?

답변

3

람다 식에서 루프 변수를 캡처 중입니다. 즉 대리인이 마지막으로 호출 될 때, 항상 될 것입니다 변수 ...의 최신 값을 사용합니다 의미 1.이 시도 :

foreach (var i in Enumerable.Range(0, 2)) 
{ 
    int copy = i; 
    SomethingHappened +=() => { Console.Write(copy); }; 
} 

이 ... 다음에 대한 Eric Lippert's blog post를 참조하십시오.

1

두 번째 프로그램에서 변수 i은 람다에 의해 캡쳐됩니다. 올바른 동작을 얻으려면 람다에서 사용하기 전에 로컬 복사본을 만드십시오. 예 :

foreach (var i in Enumerable.Range(0, 2)) 
{ 
    var local = i; 
    SomethingHappened +=() => { Console.Write(local); }; 
} 
관련 문제