[C#] 열거자(Enumerator)

Running boy·2023년 8월 6일
0

컴퓨터 공학

목록 보기
12/36

IEnumerable/IEnumerator

닷넷에서 제공하는 인터페이스이다.
IEnumerator를 구현한 객체를 열거자(enumerator)라고 한다.

// 닷넷에 정의돼 있는 IEnumerable 인터페이스
public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

// 닷넷에 정의돼 있는 IEnumerator 인터페이스
public interface IEnumerator
{
    object Current { get; } // 현재 요소를 반환하는 프로퍼티
    bool MoveNext(); // 다음 요소를 가리키는 메서드
    void Reset(); // 처음 요소를 가리키는 메서드
}

IEnumerable 인터페이스를 구현한 대표적인 예가 System.Array이다.

IEnumerable의 구현체는 다음과 같이 열람하는 것이 가능하다.

int[] intArray = new int[] { 1, 2, 3, 4, 5 };

IEnumerator enumerator = intArray.GetEnumerator();

while (enumerator.MoveNext()) // 더 이상 열거할 수 없을 때 false를 반환
{
    Console.Write(enumerator.Current + ", ");
}

// 출력:
// 1, 2, 3, 4, 5,
int[] intArray = new int[] { 1, 2, 3, 4, 5 };

foreach (int elem in intArray)
{
    Console.Write(elem + ", ");
}

// 출력:
// 1, 2, 3, 4, 5,

두 코드는 동일한 기능을 한다.
실제로 컴파일러는 컴파일 시점에 아래의 foreach문을 위의 while문으로 변환한다.
즉 IEnumerable, IEnumerator 두 인터페이스를 구현해준다면 개발자가 직접 정의한 구현체도 foreach문으로 열람이 가능하다.

정리하면

IEnumerable: 열거할 수 있는 객체라는 개념
IEnumerator: 실질적으로 열거되는 객체


구현체 예시

class Hardware { }

class USB
{
    string name;
    public USB(string name) { this.name = name; }

    public override string ToString()
    {
        return name;
    }
}

class Notebook : Hardware, IEnumerable
{
    USB[] usbList = new USB[] { new USB("USB1"), new USB("USB2") };

    public IEnumerator GetEnumerator()
    {
        return new USBEnumerator(usbList);
    }

    public class USBEnumerator : IEnumerator
    {
        int pos = -1;
        int length = 0;
        object[] list;

        public USBEnumerator(USB[] usb)
        {
            list = usb;
            length = usb.Length;
        }

        public object Current
        {
            get { return list[pos]; }
        }

        public bool MoveNext()
        {
            if (pos >= length - 1)
            {
                return false;
            }

            pos++;
            return true;
        }

        public void Reset()
        {
            pos = -1;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Notebook notebook = new Notebook();

        foreach (USB usb in notebook)
        {
            Console.WriteLine(usb);
        }
    }
}

// 출력:
// USB1
// USB2

참고 자료
시작하세요! C# 10 프로그래밍 - 정성태

profile
Runner's high를 목표로

0개의 댓글