54. 람다 클로저의 변수 캡처와 루프 변수 함정

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 주제: 람다 클로저의 변수 캡처 — "값이 아니라 변수를 캡처", 루프 변수 캡처 함정
//
// 과제:
//   1) 람다는 캡처한 변수의 "값의 스냅샷"이 아니라 변수 자체(저장 위치)를 캡처한다.
//      컴파일러가 만드는 클로저 클래스(디스플레이 클래스)와 캡처 변수의 승격(호이스팅)을
//      설명하라.
//   2) for 루프 변수와 foreach 루프 변수의 캡처가 왜 다르게 동작하는가?
//      (C# 5 에서 foreach 반복 변수 의미가 바뀐 점 포함)
//   3) 아래 프로그램의 각 구간 출력을 예측하고, 그 이유를 클로저/캡처로 설명하라.

using System;
using System.Collections.Generic;

public static class Program
{
    public static void Main()
    {
        // (1) for 루프 변수 캡처
        var a1 = new List<Action>();
        for (int i = 0; i < 3; i++)
            a1.Add(() => Console.Write(i + " "));
        foreach (var f in a1) f();
        Console.WriteLine();

        // (2) foreach 루프 변수 캡처 (C# 5+)
        var a2 = new List<Action>();
        foreach (var n in new[] { 10, 20, 30 })
            a2.Add(() => Console.Write(n + " "));
        foreach (var f in a2) f();
        Console.WriteLine();

        // (3) 캡처는 변수 참조 — 나중에 바꾸면 반영
        int x = 1;
        Action show = () => Console.Write(x + " ");
        x = 99;
        show();
        Console.WriteLine();
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.