C#

[C#]IEnumerable 인터페이스란?

DevStory 2022. 2. 6.

IEnumerable 인터페이스란?

IEnumerable은 List, Stack, Queue와 같은 컬렉션에 반복이 필요한 경우 사용되는 인터페이스입니다. 기본적으로 컬렉션은 이미 IEnumerable 인터페이스를 가지기 때문에 foreach문을 사용하여 컬렉션 요소들을 반복적으로 접근할 수 있습니다.

ArrayList

이번 포스팅에서는 IEnumerable 인터페이스와 사용자 정의 컬렉션 클래스에서 IEnumerable를 구현하는 방법을 설명합니다.

 


IEnumerable 인터페이스

IEnumerable 인터페이스는 다음과 같이 구현되어있습니다.

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

IEnumerable 인터페이스는 IEnumerator 객체를 반환하는 GetEnumerator() 메서드를 가지고 있습니다.

 

GetEnumerator() 메서드는 컬렉션의 요소를 반복적으로 접근할 수 있도록 해주는 IEnumerator 객체를 반환합니다. 


IEnumerator 인터페이스

IEnumerator 인터페이스는 다음과 같이 구현되어 있으며, Current 프로퍼티, MoveNext(), Reset() 메서드를 가지고 있습니다.

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

IEnumerator 인터페이스의 구성 요소

  • Current: 현재 요소를 반환합니다. 
  • MoveNext(): 다음 요소로 이동할 수 있는지 여부를 bool 값으로 반환합니다.
  • Reset(): 열거자를 초기 위치로 재설정하여 리스트의 처음부터 다시 반복합니다.
반응형

컬렉션 클래스 열거

List, Stack, Queue와 같은 컬렉션은 이미 IEnumerable 인터페이스를 가지고 있으며, 구현되어 있기 때문에 foreach문으로 반복적으로 컬렉션 요소를 접근할 수 있습니다.

ArrayList의 GetEnumerator() 메서드

컬렉션을 열거하는 방법은 다음과 예제처럼 foreach문을 사용합니다.

ArrayList list = new ArrayList() { 1, 2, 3 };

foreach(int item in list)
{
    Console.WriteLine("item: {0}", item);
}

 

제네릭 컬렉션을 열거하는 방법은 컬렉션과 동일합니다.

List<int> list = new List<int>() { 1, 2, 3 };

foreach(int item in list)
{
    Console.WriteLine("item: {0}", item);
}

제네릭 컬렉션 클래스는 IEnumerable<T> 인터페이스를 가지고 있으며, GetEnumerator() 메서드가 구현되어있기 때문에 반복적으로 요소를 접근할 수 있습니다.

제네릭 컬렉션 클래스


사용자 정의 컬렉션 클래스에서 IEnumerable 구현

컬렉션 그리고 제네릭 컬렉션은 이미 IEnumerable 인터페이스를 구현했기 때문에 열거 가능합니다. 사용자 정의 컬렉션 클래스에서 요소들을 반복적으로 접근하기 위해서는 클래스에서 IEnumerable 및 IEnumerator 인터페이스를 모두 구현해야 합니다.

 

순서 1. 기본 클래스를 구현합니다.

Person 클래스는 사람의 이름과 나이 정보를 가지는 클래스입니다.

public class PersonInfo
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    public PersonInfo(string _name, int _age)
    {
        this.Name = _name;
        this.Age = _age;
    }
}

 

순서 2. 열거자를 반환하는 클래스를 구현합니다.

Person 객체를 반환하는 IEnumerable 인터페이스의 GetEnumerator() 메서드를 구현합니다.

public class Persons : IEnumerable
{
    private PersonInfo[] _person;
    
    public Persons(PersonInfo[] uArray)
    {
        _person = new PersonInfo[uArray.Length];
        for (int i = 0; i < uArray.Length; i++)
        {
            _person[i] = uArray[i];
        }
    }
    
    IEnumerator IEnumerable.GetEnumerator()
    {
        return (IEnumerator)GetEnumerator();
    }
    
    public PersonsEnum GetEnumerator()
    {
        return new PersonsEnum(_person);
    }
}

 

순서 3. 컬렉션 요소를 반복적으로 접근하기 위해 IEnumerator 인터페이스를 가지는 클래스를 구현합니다.

public class PersonsEnum : IEnumerator
{
    public PersonInfo[] _person;
    int currentIndex = -1;
    
    public PersonsEnum(PersonInfo[] list)
    {
        _person = list;
    }
    
    public bool MoveNext()
    {
        currentIndex++;
        return (currentIndex < _person.Length);
    }
    
    object IEnumerator.Current
    {
        get { return Current; }
    }
    
    public PersonInfo Current
    {
        get
        {
            try
            {
                return _person[currentIndex];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
    
    public void Reset()
    {
        currentIndex = -1;
    }
}

 

main 함수

class Program
{
    static void Main(string[] args)
    {
        PersonInfo[] pInfo = new PersonInfo[3] {
            new PersonInfo("홍길동", 20),
            new PersonInfo("또치", 100),
            new PersonInfo("마이콜", 22)
        };

        Persons persons = new Persons(pInfo);

        foreach (var person in persons)
        {
            Console.WriteLine("person.Name: " + person.Name + ", person.Age: " + person.Age);
        }
    }
}

실행 결과

반응형

'C#' 카테고리의 다른 글

[C#]SortedList 클래스  (0) 2022.02.06
[C#]yield 키워드  (0) 2022.02.06
[C#]동적 변수(dynamic)  (0) 2022.02.05
[C#]익명 타입(Anonymous Type)  (0) 2022.02.05
[C#]StringBuilder 사용 방법  (1) 2022.02.05

댓글