[Unity] IEnumerator 개요

KYO
KYO
∙∙조회 6
[Unity] IEnumerator 개요

들어가며

IEnumerator? 나는 코루틴으로만 생각했던 개념이다.

그런데 최근 동시성 관련 공부를 하다가, 이게 그렇게 단순한 개념이 아니라는 것을 느꼈다.

이 글에서는 개념적인 정의와 foreach에서의 덕타이핑 사례만 간단히 짚었다.

Foreach

csharp
// 우리가 쓰는 코드
foreach (var enemy in enemies)
{
    enemy.TakeDamage(10);
}

// 컴파일러가 만드는 코드 (개념적으로)
var e = enemies.GetEnumerator();
try
{
    while (e.MoveNext())
    {
        var enemy = e.Current;
        enemy.TakeDamage(10);
    }
}
finally
{
    (e as IDisposable)?.Dispose();
}

즉 Foreach문은 특정 조건을 만족하는 객체에 대해 사용할 수 있는 문법이다. using문에 IDisposable을 넣는다는 사실을 처음 알았을 땐 적잖이 충격이었는데, 그렇게 한 번 겪어봐서인지 이번엔 그정도는 아니었다.

Foreach가 대상을 해석하는 순서는 이렇다.

  1. 배열이나 문자열이면 → 인덱스 루프로 직접 변환
  2. 공개 GetEnumerator()가 있으면 → 그걸 쓴다 (덕 타이핑)
  3. 없으면 IEnumerable<T> → IEnumerable 순으로 찾는다 (인터페이스 경유)

IEnumerable, IEnumerator, IEnumerator

csharp
public interface IEnumerable<out T>
{
    IEnumerator<T> GetEnumerator();
}

public interface IEnumerator<out T> : IEnumerator, IDisposable
{
    T Current { get; }
}

public interface IEnumerator
{
    object Current { get; }
    bool MoveNext();
    void Reset();
}

foreach(IEnumerator<T> it in IEnumerable<T>) 꼴임을 알 수 있다.

그리고 it.Current로 해당하는 객체를 가져올 수 있다.