Often in programming is necessary to create class that manages and aggregate some type of objects. In example:

  • class Cells aggregate and manage multiple Cell
  • class DNA aggregate and manage multiple Gene

It is desirable to use a Linq expressions with class that aggregate. To have ability to use Linq methods in that custom class we have to implement interface called IEnumerable or IEnumerable<>.
For example we have got a class Cell.

enum CellStates { Empty, Grain, Solid }

class Cell
{
    public CellStates State { get; set; }

    public Cell (CellStates state)
    {
        this.State = state;
    }
}

We need to have some class that can manage our Cell collection. Creating just List<Cell> cells don’t give us so much control. So we need some class that aggregates our cells. Creating class like that don’t enables the Linq mechanism.

class Cells
{
    List<Cell> cells;

    public Cells(int cellsSize)
    {
        this.cells = new List<Cell>();
        for (int i = 0; i < cells.Count; i++)
        {
            cells[i] = new Cell(CellStates.Empty);
        }
    }
}

 

var solidCells = Cells.Select(c => c.State == CellsStates.Solid); // Error!

To make that code working just implement an IEnumerable interface.

class Cells : IEnumerable<Cell>
{
    List<Cell> cells;

    public Cells(int cellsSize)
    {
        this.cells = new List<Cell>();
        for (int i = 0; i < cells.Count; i++)
        {
            cells[i] = new Cell(CellStates.Empty);
        }
    }

    #region IEnumerable
    IEnumerator<Cell> IEnumerable<Cell>.GetEnumerator()
    {
        return cells.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return cells.GetEnumerator();
    }
    #endregion
}

Of course class Cells can just derive from a List<Cell> but that reveals whole methods. And so on it breaks OOP encapsulation rule.