IEnumerable 인터페이스
Enumerator를 노출시키고 non-generic 컬렉션에 대한 순회를 할 수 있다. IEnumerable<T>는 generic 컬렉션에 대한 순회.
IEnumerable 인터페이스 정의
//
// 요약:
// Exposes an enumerator, which supports a simple iteration over a non-generic collection.
public interface IEnumerable
{
//
// 요약:
// Returns an enumerator that iterates through a collection.
//
// 반환 값:
// An System.Collections.IEnumerator object that can be used to iterate through
// the collection.
IEnumerator GetEnumerator();
}
컬렉션에서 IEnumerator를 반환하는 GetEnumerator()를 구현해야하기 때문에 실제로는 IEnumerator까지 같이 구현해야하는 경우가 많다.
IEnumerable 인터페이스를 구현한 클래스는 foreach를 이용하여 각 원소를 순회할 수 있다.
예제) Person 인스턴스를 요소로 가지는 IEnumerable 순회가능한 People 클래스
public class Person
{
public string firstName;
public string lastName;
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}
}
public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];
for(int i = 0; i < pArray.Length; ++i)
{
_people[i] = pArray[i];
}
}
// IEnumerable의 인터페이스를 구현한다. 반드시 IEnumerator를 반환하도록 하며 foreach가 해당 메서드를 사용한다.
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)GetEnumerator();
}
// 실제 순회방법을 제공하는 PeopleEnum을 따로 생성해서 이 메서드를 호출하도록 해야한다.
public PeopleEnum GetEnumerator()
{
return new PeopleEnum(_people);
}
}
IEnumerator 인터페이스
Non-generic 컬렉션에 대한 순회 방법을 제공한다. IEnumerator<T>의 경우 generic 컬렉션에 대한 순회 방법을 제공.
IEnumerator 인터페이스 정의
//
// 요약:
// Supports a simple iteration over a non-generic collection.
public interface IEnumerator
{
//
// 요약:
// Gets the element in the collection at the current position of the enumerator.
//
// 반환 값:
// The element in the collection at the current position of the enumerator.
object? Current { get; }
//
// 요약:
// Advances the enumerator to the next element of the collection.
//
// 반환 값:
// true if the enumerator was successfully advanced to the next element; false if
// the enumerator has passed the end of the collection.
//
// 예외:
// T:System.InvalidOperationException:
// The collection was modified after the enumerator was created.
bool MoveNext();
//
// 요약:
// Sets the enumerator to its initial position, which is before the first element
// in the collection.
//
// 예외:
// T:System.InvalidOperationException:
// The collection was modified after the enumerator was created.
void Reset();
}
- Current : 현재 요소를 반환하는 프로퍼티
- MoveNext : 다음 요소로 이동하는 인터페이스, 다음 요소가 컬렉션의 끝을 넘어서지 않는 다면 true를 반환
- Reset : 컬렉션에서 현재 요소를 가장 처음 요소로 재설정
예제) People 컬렉션을 순회하는 실제 Enumerator 반복자 클래스
public class PeopleEnum : IEnumerator
{
public Person[] _people;
int position = -1;
public PeopleEnum(Person[] list)
{
_people = list;
}
// IEnumerator는 MoveNext()와 Reset() 메서드를 구현해야한다.
public bool MoveNext()
{
position++;
return (position < _people.Length);
}
public void Reset()
{
position = -1;
}
// IEnumerator는 Current 요소를 반환해야하는 인터페이스를 구현해야한다.
object IEnumerator.Current { get { return Current; } }
public Person Current
{
get
{
try
{
return _people[position];
}
catch(IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
IEnumerable과 IEnumerator를 사용하여 다음과 같이 foreach를 사용할 수 있게 된다.
class Program
{
static void Main(string[] args)
{
Person[] peopleArray = new Person[3]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
};
People peopleList = new People(peopleArray);
foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);
}
}
'C# > C# 인터페이스' 카테고리의 다른 글
C# 인터페이스 vs 추상 클래스 (0) | 2022.04.09 |
---|---|
C# 공변성과 반공변성 Covariance / Contravariance (0) | 2021.11.20 |
IComparable/IComparer/IEquatable : 비교와 관련된 인터페이스 (0) | 2021.11.13 |
ICollection : 컬렉션 인터페이스 (0) | 2021.11.13 |
IDisposable : 비관리 리소스 해제하기 (0) | 2021.11.12 |