이전 글에서 yield return 을 사용하면 함수 실행을 중간에 멈췄다가 다시 실행할 수 있다는 것을 배웠습니다. 그렇다면, C# 은 어떻게 이를 가능하게 할까요? 이번 글에서는 yield return 이 내부적으로 어떻게 동작하는지 알아보겠습니다.
yield return 이 포함된 함수는 컴파일 단계에서 변환된다
yield return 을 포함한 함수는 일반적인 함수처럼 작동하는 것이 아니라, 컴파일러에 의해 특별한 클래스로 변환됩니다. 즉, C# 컴파일러는 해당 함수를 IEnumerator 인터페이스를 구현하는 클래스로 변환하여 실행 흐름을 제어합니다. 예를 들어, 다음 코드를 보겠습니다:
IEnumerator MyCoroutine()
{
Console.WriteLine("Step 1");
yield return null;
Console.WriteLine("Step 2");
yield return null;
Console.WriteLine("Step 3");
}
이 함수는 컴파일러에 의해 아래와 같이 변환됩니다.
class MyCoroutineState : IEnumerator
{
private int state = 0;
public object Current { get; private set; }
public bool MoveNext()
{
switch (state)
{
case 0:
Console.WriteLine("Step 1");
Current = null;
state = 1;
return true;
case 1:
Console.WriteLine("Step 2");
Current = null;
state = 2;
return true;
case 2:
Console.WriteLine("Step 3");
state = -1;
return false;
}
return false;
}
public void Reset() { state = 0; }
}
컴파일러는 yield return 을 만나면 현재 상태를 저장하고(state 변수), 다음 실행될 위치를 기록하여 중단할 수 있도록 변환합니다. 그리고 MoveNext()가 호출되면 저장된 위치에서 다시 실행을 시작합니다.
MoveNext() 는 어떻게 실행 흐름을 제어할까?
위 코드에서 MoveNext() 메서드는 switch 문을 사용하여 현재 실행 위치를 추적합니다.
state 값이 0이면, Step 1을 출력하고 yield return null 을 만나서 중단합니다.
MoveNext() 가 다시 호출되면 state가 1이므로, Step 2를 출력하고 다시 멈춥니다.
마지막 Step 3을 출력한 후 state = -1로 설정되어 종료됩니다. 즉, MoveNext()는 실행 흐름을 기억하고 있다가, yield return을 만날 때마다 중단하고 나중에 다시 실행할 수 있도록 관리하는 역할을 합니다.
IEnumerator 와 yield return의 관계
이제 yield return이 어떻게 실행되는지 이해했다면, IEnumerator 와의 관계도 명확해집니다.
yield return 이 포함된 함수는 IEnumerator 를 반환하는 함수여야 합니다.
IEnumerator 는 MoveNext() 를 호출하면서 실행 위치를 관리합니다.
Unity에서 StartCoroutine()을 사용하면 내부적으로 MoveNext()를 주기적으로 호출하여 실행을 관리합니다. 즉, IEnumerator는 yield return을 사용하여 중단과 재개를 가능하게 하는 기반이 되는 인터페이스입니다.
마무리
yield return이 포함된 함수는 일반적인 함수가 아니라, 컴파일러에 의해 IEnumerator를 구현하는 클래스로 변환됩니다.
변환된 클래스는 MoveNext() 메서드를 사용하여 실행 위치를 관리하고, yield return을 만나면 멈췄다가 다시 실행될 수 있습니다.
IEnumerator는 MoveNext()를 호출하면서 실행 흐름을 제어하는 핵심 인터페이스이며, StartCoroutine()을 통해 Unity에서 이를 활용할 수 있습니다.
이번 글에서는 yield return이 내부적으로 어떻게 동작하는지 살펴보았습니다. 다음 글에서는 yield return이 코루틴과 어떻게 연결되는지 더 자세히 알아보겠습니다!
'C#' 카테고리의 다른 글
4. yield return 에 대해 ( 활용 01 ) (0) | 2025.03.09 |
---|---|
3. yield return 에 대해 (유니티에서의 동작) (0) | 2025.03.09 |
1. yield return 에 대해 (개념) (0) | 2025.03.09 |
Action 과 Func 의 형변환 살펴보기 (0) | 2025.03.08 |
=> (람다 연산자) 이해하기 (0) | 2025.03.08 |