[Unity/C#]열거자 : Enumerator

강동현·2024년 1월 24일
0

Unity/C#

목록 보기
16/26
  • 답답해서 내가 설명해준다.
  • Why: 너가 생성한 클래스에서 foreach를 쓰고 싶어 -> 이때 사용
  • Enumerable = 순회 가능한 클래스
  • Enumerator = 순회 가능한 클래스 내부 순회기

열거자(Enumerator = Iterator)

  • 클래스원소(데이터 요소)하나씩 리턴
  • 클래스 순회

열거자 필수조건

  • Enumerable 클래스 내부

    1. GetEnumerator() 함수
  • Enumerator 클래스 내부

      1. bool MoveNext() 함수
      1. object타입 Current 속성(프로퍼티)

열거자 내부 로직

  • 열거자 내부 실행 로직
    private void Start()
    {
        MyList myList = new MyList();
        MyList.Enumerator e = myList.GetEnumerator();
        while (e.MoveNext())
        {
            Debug.Log(e.Current);
        }
    }

IEnumerator / IEnumerable

  • 열거자 선언 매우 복잡
  • Enumerator/Enumerable 선언 시 실수 방지를 위한 Interface
  • [★]순회를 원하는 클래스 = IEnumerable 상속
  • [★]순회를 원하는 클래스 내 Enumerator 클래스 생성 & IEnumerator 상속
  • Enumerator컬렉션을 순회하기 위해 사용
    • 전처리 구문
    using System.Collections;
  • 인터페이스에 따른 함수 자동 구현
  • IEnumerable
    • 1. GetEnumerator
    // 닷넷에 정의돼 있는 IEnumerable 인터페이스
    public interface IEnumerable
    {
        IEnumerator GetEnumerator();
    }
  • IEnumerator
    • 2. MoveNext
    • 3. Current
    • 4. Reset
    // 닷넷에 정의돼 있는 IEnumerator 인터페이스
    public interface IEnumerator
    {
        object Current { get; } // 현재 요소를 반환하는 프로퍼티
        bool MoveNext(); // 다음 요소를 가리키는 메서드
        void Reset(); // 처음 요소를 가리키는 메서드
    }

융합

public class MyList : IEnumerable
{
	public IEnumerator GetEnumerator(){
    	IEnumerator enumerator = new enumerator();
        return enumerator;
    }
    public class enumerator : IEnumerator
    {
    	 int[] num = new int[5] {1,2,3,4,5};
         int index = -1;
         public object Current { get { return num[index]; } }
         public bool MoveNext()
         {
         	if(index == num.Length-1) return false;
            ++index;
            return index < num.Length;
         }
         public void Reset()
         {
         	index = -1;
         }
    }
}

yield return;

  • 복잡한 열거자 선언을 더욱 단축
  • 아래 코드는 위 코드와 동일
    • but 코드의 효율성이 다름
public class MyList
{
	public IEnumerator GetEnumerator()
    {
    	int[] num = new int[5]{1,2,3,4,5};
        int index = -1;
        while(index < num.Length - 1)
        {
        	++index;
            yield return num[index];
        }
    }
}
  • C# 컴파일러컴파일단계에서 Enumerator 클래스 생성
    • Current 속성bool MoveNext() 보유
    • IEnumerable / IEnumerator 상속
    • 즉, yield return으로 GetEnumerator() 함수 구현 시, 간단히 Enumerator 구현

yield return 특징

  • yield를 만나는 부분에서 실행 중단(양보)
  • 다음 호출에 중단된 부분에서 다시 실행
//내부 로직
index++;
yield return num[index];//중단
index++;
yield return num[index];//중단
index++;
yield return num[index];//중단

yield break;

  • yield를 만나는 부분에서 종료
public IEnumerator GetEnumerator()
{
	int[] num = new int[5]{1,2,3,4,5};
    int index = -1;
    while(index < num.Length-1){
    	++index;
        if(index == 4) yield break;
        yield return num[index];
    }
}
//1 2 3 4 [출력] 5 [출력 X]

Start Coroutine

  • StartCoroutine()은 내부적으로 아래 코드를 수행
StartCoroutine(enumerator);
void Start()
    {
        IEnumerator enumerator = SomeNumbers();
        while (enumerator.MoveNext()) 
        {
            object result = enumerator.Current;
            Debug.Log("Number: " + result);
        }
    }
profile
GAME DESIGN & CLIENT PROGRAMMING

0개의 댓글