2016-06-09 4 views
0

코드의 조각을 봐루프 내부 대표는 지역 및 루프 변수의 차이를 이해하는 방법

List<Action> actions = new List<Action>(); 
    for (int variable = 0; variable < 5; ++variable) 
     { 
      int myLocalVariable = variable; 
      actions.Add(() => Console.WriteLine(myLocalVariable)); 
     } 
    actions.ForEach(s => s.Invoke()); 
    Console.ReadLine(); 

출력은 내가 생각하는 경향이 IL 코드를 보면 0 1 2 3 4

입니다 이 컴파일러는 myLocalVariable 인스턴스를 하나만 만듭니다. 이 사실은 또한 루프 내에서 지역 변수를 사용하는 것이 좋습니다.

그래서 내부에서 위임 한 actions.Add()는 루프 변수의 "최신"버전을 저장합니다.

답변

5

IL 코드를 보면 컴파일러가 myLocalVariable 인스턴스를 하나만 생성한다고 생각하는 경향이 있습니다.

아니요. C# 언어 사양은 루프가 반복 될 때마다 변수가 인스턴스화된다는 것을 명확하게 보여주기 때문에 각 반복마다 별도의 변수가 있으므로 별도로 캡처됩니다.

는 C# 5 스펙의 섹션 7.5.15.2 가입일 : 로컬 변수가 실행 변수의 범위에 들어갈 때 인스턴스화 간주

. 예를 들어, 다음 메소드가 호출되면 로컬 변수 x가 인스턴스화되고 루프 반복마다 3 회 초기화됩니다.

static void F() { 
    for (int i = 0; i < 3; i++) { 
     int x = i * 2 + 1; 
     ... 
    } 
} 

그러나 ... x

의 단일 인스턴스에서 루프 결과 외부 x의 선언을 이동하는

캡처되지

, 관찰 할 수있는 방법은 없습니다 정확히 얼마나 자주 현지를 변수는 인스턴스화됩니다. 인스턴스화의 수명이 서로 다르기 때문에 각 인스턴스가 단순히 동일한 저장 영역 위치를 사용할 수 있습니다. 그러나 익명 함수가 지역 변수를 캡처하면 인스턴스화의 영향이 명확 해집니다.

+0

ok, 익명 함수가 로컬 인스턴스 변수 (myLocalVariable)의 값을 캡처하고 해당 값의 복사본을 내부적으로 저장합니다.이 경우 루프 변수의 값 복사본을 저장할 수 있습니다. , 익명 함수 로컬 변수 VS 루프 변수의 차이점은 무엇입니까 @JonSkeet –

+0

@VladimirGabrielyan : 아니요, 루프 변수가 'for'루프에 대해서만 한 번만 인스턴스화되도록 지정 되었기 때문에 아니요. 'foreach' 루프의 경우, 한번 인스턴스화하기 위해 * 사용되었지만 C# 5에서 고정되어 반복마다 인스턴스화됩니다. –