C#에서 열거자(Enumerator)는 컬렉션을 순회(traverse) 메커니즘을 정의하는 인터페이스이다.
열거자는 컬렉션을 순회할 때 사용되며, 컬렉션의 각 요소에 순차적으로 접근하는 방법을 제공한다. IEnumerator 또는 IEnumerator<T> 인터페이스를 구현할 시 foreach문으로 요소를 순회할 수 있게 된다.
public interface IEnumerator
{
bool MoveNext();
object Current { get; }
void Reset();
}
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
for (int i = _length - 1; i >= 0; i--)
{
yield return _items[i];
}
}
class Program
{
static void Main()
{
// List<T>는 IEnumerable<T> 인터페이스가 구현되어 있다.
List<int> numbers = new List<int> {1, 2, 3, 4, 5};
// 따라서 foreach 문을 사용하여 List<T>의 요소를 순회할 수 있다.
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
}
yield return는 '여기서 멈추고 값을 반환해, 다음에 다시 호출되면 이어서 진행해'라는 의미. 언제까지? 해당 이터레이터 함수가 끝날 때까지 혹은 yield break를 만날 때까지.
foreach (int fib in Fibs(6))
{
Console.Write(fib + " ");
}
IEnumerable<int> Fibs (int fibCount)
{
for (int i = 0, prevFib = 1, curFib = 1; i < fibCount; i++)
{
yield return prevFib; // enumerator에 의해 배출될 다음 요소
int newFib = prevFib+curFib;
prevFib = curFib;
curFib = newFib;
}
}
// OUTPUT: 1 1 2 3 5 8
ICollection<T> ICollection은 C#의 컬렉션 관련 인터페이스 중 하나로,
IEnumerable<T> IEnumerable을 확장한 버전이다 (아이템 추가, 삭제, 검색, 카운트)
public interface ICollection<T> : IEnumerable<T> // 제네릭 버전
{
int Count { get; }
bool Contains (T item); // 컬렉션에 해당 아이템이 들어있는지 검사
void CopyTo (T[] array, int arrayIndex); // 컬렉션의 내용을 기존 배열에 복사
bool IsReadOnly { get; } // // 컬렉션이 읽기 전용인지 검사
void Add(T item); // 컬렉션에 아이템을 추가
bool Remove (T item); // 컬렉션에 아이템을 삭제
void Clear(); // 컬렉션에 모든 아이템을 삭제
}
public interface ICollection : IEnumerable // 비제네릭 버전
{
int Count { get; }
bool IsSynchronized { get; }
object SyncRoot { get; }
void CopyTo (Array array, int index);
}
IList<T> IList는 C#의 컬렉션 관련 인터페이스 중 하나로,
ICollection<T> ICollection을 더 확장한 버전. 순서가 중요한 컬렉션을 다룰 때 사용함. 특정 위치의 아이템을 제거하거나, 인덱스로 아이템을 가져오는 등의 작업을 할 수 있다.
public interface IList<T> : ICollection<T> // 제네릭 버전
{
T this [int index] { get; set; } // 인덱서
int IndexOf (T item); // 특정 아이템의 인덱스를 찾음
void Insert (int index, T item); // 특정 인덱스에 아이템을 삽입
void RemoveAt (int index); // 특정 인덱스의 아이템을 제거
}
public interface IList : ICollection // 비제네릭 버전
{
object this [int index] { get; set; }
bool IsFixedSize { get; }
bool IsReadOnly { get; }
int Add(object value);
void Clear();
bool Contains(object value);
int IndexOf(object value);
void Insert(int index, object value);
void Remove(object value);
void RemoveAt(int index);
}