삽질의 현장/- .NET

#045_닷넷(.NET)_.Net Framework 기본 - IEnumerable & IEnumerator

shovelman 2015. 10. 29. 16:29


안녕하세요 삽잡이입니다.


이번 시간에는 닷넷에서 제공하는 BCL에 있는 인터페이스를 살펴보려고합니다.

우리가 살펴보고자 하는 인터페이스는

바로, 'IEnumerable', 'IEnumerator' 입니다.


우리는 이미 BCL에서 제공하는 이 인터페이스들을 사용했었습니다.

foreach 문에서 사용을 하고 있었지요...



foreach 문에서는 배열 타입의 각 항목을 반복할 수 있다는 사실을 알고 있었습니다.

왜 배열 타입의 항목만을 반복할 수 있다 했을까요?

사실, arr은 '약속'을 지키고 있었기 때문입니다.


foreach 문은 일반 객체가 아닌 배열이나 리스트의 컬렉션에서만 사용이 가능합니다.

따라서 일반 객체도 '약속'을 지킨다면 foreach문을 실행시킬 수 있습니다. 


컴파일러는 IEnumerable을 구현했다고 가정을 하는 것입니다.

만약, IEnumerable이 구현되어있지 않다면 에러가 발생했을 것입니다.


IEnumerable은 

Enumerable 즉, '나열 가능한', '순서대로 읽어올 수 있는'이라는 뜻을 가지고 있으며,

'I' 가 접두어로 붙어있으니 인터페이스라는 사실을 알 수 있습니다.


이 인터페이스를 구현하는 클래스는 '열거가 가능한' 클래스가 됩니다.


IEnumerable은 실제 동작하는 놈(IEumerator의 객체)을 반환한다고 생각하시면 됩니다.

즉, IEnumerator GetEnumerator(); 를 반환하는 것이지요...

이 말은 곳 내부 항목이 열거될 수 있음 을 알리는 것입니다.


이 IEnumerator 인터페이스에는 세가지의 메서드가 있습니다.

MoveNext(), Current, Reset 이렇게 말입니다...


음... 정리를 해보자면,

IEnumerable 인터페이스는 내부에는 GetEnumerator() 라고... 

IEnumerator를 리턴하는 메서드가 있습니다.

즉, IEnumerable 인터페이스는 반복할 수 있는 열거자를 return 하는 것입니다.

이 열거자(IEnumerator)를 통해 컨테이너의 내부 항목을 얻어올 수 있게 됩니다.


왜 IEnumerator만 구현하면 되지, 

굳이 IEnumerable 인터페이스까지 만들어서 두 개를 만들었을까요...

이는 바로 지원과 구축을 나누어 놓은 것입니다.


어렵게 생각하지 않으셔도 됩니다.

단지 C++ 때 vector 및 list에 접근하기 위해 사용되던 

이터레이터(Iterator)와 비슷한 개념입니다.

즉, 모든 원소를 처름부터 쭈욱 돌아보는 기능과 다를 것이 없다 이겁니다.


IEnumerable는 나열을 해 놓았다면,

실제로 순회하며 활동하는 놈은 바로 IEnumerator이지요...


예를들어 IEnumerable 인터페이스를 구현한 클래스가 'Car'라고 해보겠습니다.

이 때에 Car 클래스를 carLot이라는 참조자를 통해 객체 생성을 했다면,

우리는 일반객체이지만 Car 클래스를 foreach문에서 사용할 수 있습니다.



이와 같은 코드는 사실 이와 같은 코드로 해석됩니다.




다시 말씀드리지만, 어떤 객체던지 IEnumerable 인터페이스를 구현했다면, 

foreach 문을 사용할 수 있습니다.

그런데 자료 구조 형식이 포함되어있는 클래스들이 대부분 인터페이스 구현을 많이 하겠지요...



다음으로는 yield 키워드를 살펴보겠습니다.

이 키워드를 사용하게 되면 원하는 형태로 출력 순서나, 횟수를 변경해서 출력이 가능합니다.

사실, 매번 IEnumerator를 구현하기 귀찮으니 만들어진 키워드이지요...

믿거나 말거나...


예시를 한번 살펴보시길 바랍니다.



규칙성을 찾아볼 수 있습니까?

이와 같이 규칙성 없는 경우에도 yeild return을 통해 Iterator가 만들어져 사용이 가능해집니다.

IEnumerator를 자동으로 만들어주는 것이지요...

즉, IEnumerator를 반환하는 곳에 사용하게 되면

자동적으로 Enumerator를 만들어줍니다.


BCL에서 제공하는 인터페이스가 이것밖에 되지 않을까요?
닷넷에서 사용되는 인터페이스의 개수는 어마어마하지만,

일반적으로 많이 사용되는 인터페이스입니다.



이번 시간은 여기까지 알아보도록 하겠습니다.


이상 삽잡이였습니다!



<참고 : C# and the .NET4 Platform>