Programování
Iterator
Prochází nějakou strukutru, například List nebo Array. Obsahuje dvě věci:
Vytvoříme si třídu MyList která bude mít array s 10 prvky a chceme aby dávkoval prvky uvnitř té třídy.
- Referenci na aktualní object
- Ví jak přejít na další objekt
Vytvoříme si třídu MyList která bude mít array s 10 prvky a chceme aby dávkoval prvky uvnitř té třídy.
public class MyList
{
private int[] data = new int[] { 5,2,1,3,4,8,7,9,5,4,8,1,5};
}
Následně si vytvoříme náš vlastní iterátor. MUSÍ Obsahovat dvě metody
- public bool HasNext
- public int GetNext
public class MyListIterator
{
private int[] data;
private int current = 0;
public MyListIterator(int[] data)
{
this.data = data;
}
public bool HasNext()
{
return current < data.Length;
}
public bool GetNext()
{
return data[current++];
}
}
Použíjeme tak, že získání iteratoru vložime do třídy MyList, přes který budeme následně získávat iterátor.
public class MyList
{
private int[] data = new int[] { 5,2,1,3,4,8,7,9,5,4,8,1,5};
public MyListIterator GetIterator()
{
return new MyListIterator(data);
}
}
// V mainu budeme procházet:
MyList list = new MyList();
MyListIterator iterator = list.GetIterator();
while(iterator.HasNext())
{
Console.WriteLine(iterator.GetNext());
}
Nyní jsme si napsali nás vlastní foreach přes while loop. Na to abychom mohly používat foreach, musime dědit z IEnumerator<>.
public class MyListEnumerator : IEnumerator<int>
{
public bool MoveNext() // Další prvek
{
throw new NotImplementedException();
}
public void Reset() // Resetovani
{
throw new NotImplementedException();
}
public int Current { get; }
object IEnumerator.Current => Current;
public void Dispose() //Na vymazani
{
throw new NotImplementedException();
}
}
Kdybychom dosadily potřebne hodnoty, dostali bychom se ke stejnému výsledku jako u iterátoru, avšak máme pro toto lepší způsob.
Vytvoříme si novou metodu "GetEnumerator" v MyList
public class MyList
{
private int[] data = new int[] { 5,2,1,3,4,8,7,9,5,4,8,1,5};
public IEnumerator<int> GetEnumerator()
{
for (int i = 0; i < count; i++)
{
yield return data[i];
// Virtualně pozastaví do každého prvku
}
}
}
// V mainu budeme procházet:
MyList list = new MyList();
IEnumerator@("") en = list.GetEnumerator();
while(en.MoveNext())
{
int current = en.Current;
Console.WriteLine(current);
}
// Nebo
// Pozor musí obsahovat se stejným názvem
// "public IEnumerator<int> GetEnumerator()"
foreach (var cislo in list)
{
Console.WriteLine(cislo);
}
Bonus
Procházení souboru iterátorem
public class IterableFile
{
public string File { get; set; }
public IterableFile(string file)
{
File = file;
}
public IEnumerator<string> GetEnumerator()
{
using (var reader = new StreamReader(File))
{
while (!reader.EndOfStream)
{
yield return reader.ReadLine();
}
}
}
}
// V mainu
IterableFile iterable = new IterableFile("Cesta")
foreach(string text in iterable)
{
Console.WriteLine(text);
}