- 답답해서 내가 설명해준다.
Why
: 너가 생성한 클래스
에서 foreach
를 쓰고 싶어 -> 이때 사용
- Enumerable = 순회 가능한 클래스
- Enumerator = 순회 가능한 클래스 내부 순회기
열거자(Enumerator = Iterator)
클래스
의 원소(데이터 요소)
를 하나씩 리턴
클래스
순회
열거자 필수조건
Enumerable 클래스 내부
1. GetEnumerator() 함수
Enumerator 클래스 내부
bool MoveNext() 함수
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
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
- IEnumerator
2. MoveNext
3. Current
4. Reset
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;
- 복잡한 열거자 선언을
더욱 단축
- 아래 코드는 위 코드와 동일
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;
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];
}
}
Start Coroutine
- StartCoroutine()은 내부적으로 아래 코드를 수행
StartCoroutine(enumerator);
void Start()
{
IEnumerator enumerator = SomeNumbers();
while (enumerator.MoveNext())
{
object result = enumerator.Current;
Debug.Log("Number: " + result);
}
}