How to Use the Iterator Pattern in C#
the
iterator pattern provides a process to obtain the aggregator object without
knowing its implementation.
Use
Case
Let
us take an example of a collection list of cars and string[] an array of
motorcycles; we need to design an aggregator object to iterate over the
collection without knowing whether it's a list or an array.
The iterator
design pattern helps solve this problem wherein a standard iterator
will traverse different collection types.
Prerequisites
- Basic knowledge of
OOPs concepts.
- Any programming
language knowledge.
The
article demonstrates the usage of iterator design patterns using the C#
programming language.
Getting
Started
Considering
the above use case, let us define a custom iterator interface that acts as an
abstract layer over the list and array iterator.
public interface IVehicleIterator{
void First();
bool IsDone();
string Next();
string Current();
}
CarIterator.cs
The
car iterator is implemented over List<string>collection and provides
an implementation of interface methods.
public class CarIterator : IVehicleIterator
{
private List<string> _cars;
private int _current;
public CarIterator(List<string> cars)
{
_cars = cars;
_current = 0;
}
public string Current()
{
return _cars.ElementAt(_current);
}
public void First()
{
_current = 0;
}
public bool IsDone()
{
return _current >= _cars.Count;
}
public string Next()
{
return _cars.ElementAt(_current++);
}
}
MotorcycleIterator.cs
The
motorcycle iterator is implemented over string[ ] collection and provides an
implementation of interface methods.
public class MotercycleIterator : IVehicleIterator
{
private string[] _motercylces;
private int _current;
public MotercycleIterator(string[] motercylces)
{
_motercylces = motercylces;
_current = 0;
}
public string Current()
{
return _motercylces[_current];
}
public void First()
{
_current = 0;
}
public bool IsDone()
{
return _current >= _motercylces.Length;
}
public string Next()
{
return _motercylces[_current++];
}
}
After
all the above iterators are defined, define a standard aggregator object
interface that creates iterators.
public interface IVehicleAggregate{
IVehicleIterator CreateIterator();
}
Finally,
write down the classes which implement the above aggregator interface.
According to the use-case, both Car and Motorcycle classes will implement the
aggregator interface.
Car.cs
The
method of aggregator interface returns the relevant iterator as shown below.
public class Car : IVehicleAggregate
{
private List<string> _cars;
public Car()
{
_cars = new List<string> { "Car 1", "Car 2", "Car 3" };
}
public IVehicleIterator CreateIterator()
{
return new CarIterator(_cars);
}
}
Motorcycle.cs
The
method of aggregator interface returns the relevant iterator as shown below.
public class Motercycle : IVehicleAggregate
{
private string[] _motercycles;
public Motercycle()
{
_motercycles = new[] { "Bike 1", "Bike 2", "Bike 3" };
}
public IVehicleIterator CreateIterator()
{
return new MotercycleIterator(_motercycles);
}
}
Iterator
Pattern in Action
static void Main(string[] args)
{
IVehicleAggregate car = new Vehicles.Car();
IVehicleAggregate motercycle = new Vehicles.Motercycle();
IVehicleIterator carIterator = car.CreateIterator();
IVehicleIterator motercycleIterator = motercycle.CreateIterator();
PrintVehicles(carIterator);
PrintVehicles(motercycleIterator);
}
static void PrintVehicles(IVehicleIterator iterator)
{
iterator.First();
while (!iterator.IsDone())
{
Console.WriteLine(iterator.Next());
}
}
The
PrintVehicles methods check if !iterator.isDone then output the collection element. No matter
what collection we’re dealing with, implement methods like First, IsDone, and
Next.
Output
We
don’t know the underlying collection type, but it is still iterated over it via
Iterator Design Pattern. If you go ahead and run, it displays the following
output:
Thank
you for reading, and I hope you liked the article. Please provide your feedback
in the comment section.
Comments
Post a Comment