6. yield return 이터레이터의 상태 머신과 지연 실행
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// ============================================================================
// [언어 내부동작 문제] C# - yield return 이터레이터의 상태 머신과 지연 실행
// ----------------------------------------------------------------------------
// 주제: yield return 으로 만든 이터레이터가 컴파일러가 생성한 상태 머신으로 어떻게
// 동작하는지, "지연 실행(deferred execution)" 이 무엇을 의미하는지.
//
// 과제(코드를 고치는 문제가 아니라, 출력과 내부 동작을 예측·설명하는 문제):
// 1) Main 의 전체 콘솔 출력을 줄 단위로 정확히 예측하라. 특히 "created" 와 "start" 중
// 무엇이 먼저 출력되는가?
// 2) 같은 시퀀스(seq)를 두 번 foreach 로 열거하면 "start"/"end" 가 몇 번 출력되는가?
// 그 이유를 상태 머신(MoveNext/Current) 관점에서 설명하라.
// 3) WithThrow() 를 "호출만" 하고 열거하지 않으면 예외가 나는가? 열거를 시작하면
// 언제 예외가 관측되는가?
// 4) LINQ 의 Where/Select 같은 연산이 이 "지연 실행" 과 어떻게 연결되는지 설명하라.
// (먼저 직접 예측을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
using System;
using System.Collections.Generic;
class Program
{
static IEnumerable<int> Numbers()
{
Console.WriteLine("start");
for (int i = 0; i < 3; i++)
{
Console.WriteLine($"yield {i}");
yield return i;
}
Console.WriteLine("end");
}
static IEnumerable<int> WithThrow()
{
Console.WriteLine("before first yield");
yield return 1;
throw new InvalidOperationException("boom");
}
static void Main()
{
var seq = Numbers(); // (1) 이 시점에 "start" 가 출력되는가?
Console.WriteLine("created");
foreach (var n in seq)
Console.WriteLine($"got {n}");
Console.WriteLine("--- second pass ---");
foreach (var n in seq) // (2) 같은 seq 재열거
Console.WriteLine($"got {n}");
Console.WriteLine("--- throwing iterator ---");
var bad = WithThrow(); // (3) 호출만. 예외가 나는가?
Console.WriteLine("called WithThrow");
// 이후 bad 를 열거하면 어떻게 되는지 예측하라.
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.