Custom collection
Learn to write your own IEnumerable<T> collection.
Write your own collection
Implement IEnumerable<T> on a class and it gains foreach support. The simplest path is to hold an inner List<T> and route GetEnumerator to it.
Example: class NumberBag : IEnumerable<int>. Add an Add method; in GetEnumerator return _items.GetEnumerator(). Now you can write foreach (var n in bag).
How to write GetEnumerator
IEnumerable<T> demands two GetEnumerator methods: a generic one returning IEnumerator<T> and a non-generic one returning IEnumerator. Routing both to the inner list is easiest.
The non-generic version is for legacy foreach compatibility. The signature: IEnumerator IEnumerable.GetEnumerator() => _items.GetEnumerator();. When both methods route to the same inner list, the collection is ready.
Exercise Write a NumberBag collection
The NumberBag class below implements IEnumerable<int> but lacks GetEnumerator. Add the generic GetEnumerator method returning _items.GetEnumerator(). In Main iterate with foreach and print each item.
Show example solution
Write public IEnumerator<int> GetEnumerator() { return _items.GetEnumerator(); }. In Main add foreach (var n in bag) Console.WriteLine(n);.
Example solution:
using System;
using System.Collections;
using System.Collections.Generic;
class NumberBag : IEnumerable<int>
{
private List<int> _items = new List<int>();
public void Add(int n) => _items.Add(n);
public IEnumerator<int> GetEnumerator()
{
return _items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => _items.GetEnumerator();
static void Main()
{
var bag = new NumberBag();
bag.Add(1);
bag.Add(2);
bag.Add(3);
foreach (var n in bag)
{
Console.WriteLine(n);
}
}
}
Test yourself
-
Which interface for foreach?
- IDisposable
- IClonable
- IComparable
- IEnumerable<T>
Show answer
IEnumerable<T> — Correct. A class implementing IEnumerable<T> can be iterated with foreach.
-
Implement the interface
class NumberBag : IEnumerable<____>Show answer
class NumberBag : IEnumerable<int> -
Match the part to its role
- Add
- Adds an item
- GetEnumerator
- Returns iterator
- _items
- Inner list
- IEnumerable<T>
- Iteration contract