Rozhraní IEnumerable je základním stavebním kamenem práce s kolekcemi v prostředí .NET. Definuje mechanismus, který umožňuje procházet prvky kolekce jeden po druhém, aniž by bylo nutné znát konkrétní způsob uložení dat v kolekci. Toto je realizováno s využitím enumerátoru.

IEnumerable i IEnumerator mají generickou i konkrétní variantu. Generická se nachází v namespace System.Collections.Generic;

IEnumerator

Enumerator je objekt, který umožňuje procházet (iterovat) prvky kolekce jednu položku po druhé. Slouží jako prostředník mezi kolekcí a kódem, který ji chce procházet.

Enumerator poskytuje tři klíčové členy:

  • MoveNext() – posune enumerátor na další prvek v kolekci. Vrací true, pokud existuje další prvek, nebo false, pokud kolekce skončila.
  • Current – vrací aktuální prvek kolekce. Volání je platné pouze tehdy, pokud se enumerátor nachází na platné pozici (tedy po úspěšném MoveNext()).
  • Reset() – nastaví enumerátor před první prvek kolekce. Tato metoda není vždy implementována a nemusí být podporována u všech kolekcí.

Příklad použití enumerátoru bez foreach:

IEnumerable<int> cisla = new List<int> { 10, 20, 30 };
 
using IEnumerator<int> enumerator = cisla.GetEnumerator();
 
while (enumerator.MoveNext())
{
    int prvek = enumerator.Current;
    Console.WriteLine(prvek);
}

Využití IEnumerable

  • Iterace – umožňuje používat konstrukce jako foreach, které skrývají detaily volání GetEnumerator() a MoveNext().
  • Zřetězení operací – metody LINQ (například Where, Select, OrderBy) vracejí opět IEnumerable<T>, což umožňuje řetězit více operací za sebou.
  • Zpožděné vyhodnocení (deferred execution) – operace nad IEnumerable často nejsou vykonány ihned, ale až ve chvíli, kdy se začnou skutečně číst výsledky kolekce (například v foreach). To umožňuje úsporu paměti a lepší výkon.

Fungování operací nad IEnumerable

Pokud se nad objektem typu IEnumerable volají metody jako Where, Select nebo další LINQ operace, nevytváří se ihned nová kolekce. Místo toho se vytváří „výpočetní řetězec“, který se provede až v okamžiku, kdy je potřeba získat data. Tento princip se nazývá zpožděné vyhodnocení (deferred execution).

using System.Linq;
using System.Collections.Generic;
 
// Vygenerování prvků od 1 do 10 a uložení
IEnumerable<int> cisla = Enumerable.Range(1, 10);
 
// V tuto chvíli se nic nevyhodnocuje
var sude = cisla.Where(x => x % 2 == 0);
 
// Vyhodnocení proběhne až zde - je nutné získat obsah proměnné "sude"
foreach (var cislo in sude)
{
    Console.WriteLine(cislo);
}