Introduction
In my previous article How to use the IEnumerable/IEnumerator interface, I discussed how to use these interfaces with collection classes.
Today we will see how these interfaces work. For that we will develop our own classes that implement these interfaces.
Objective
Define the Enumerable and Enumerator object for the user defines data type (i.e., class).
Using the code
First of all, let’s define a class for which we are going to develop the Iterator classes. Here is the class:
class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public override string ToString()
{
return string.Join(" | ", FirstName, LastName, Age);
}
}
As you can see, here we define the Employee
class. This class has three properties – FirstName
, LastName
, and Age
and an override method
ToString
which returns a string representation of the class. Now we’ll define the Enumerable class for Employee
called
EmployeeCollection
which implements the System.Collection.IEnumerable
interface. This class contains
an Array
of the Employee
class as its data member. This member is initialized in the constructor as shown below:
public EmployeeCollection(Employee[] listEmployee)
{
employess = new Employee[listEmployee.Length];
Array.Copy(listEmployee, employess, listEmployee.Length);
}
In this example, we are implementing the IEnumerable
interface explicitly. The reason for doing this is while using the GetEnumerator
method,
I want the user to only get my version of the GetEnumerator
method. Let us see how to do this:
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator() as IEnumerator;
}
public EmployeeEnumerator GetEnumerator()
{
return new EmployeeEnumerator(employess);
}
This way we can hide IEnumerable
’s method implementation with our own version. Till now we had developed an Enumerable class for our own class.
Now we are going to define the Enumerator class for our entity. Below we’ve the code for the Enumerator class.
class EmployeeEnumerator : IEnumerator
{
Employee[] employess;
int position = -1;
public EmployeeEnumerator(Employee[] lstEmployee)
{
employess = lstEmployee;
}
public Employee Current
{
get
{
try
{
return employess[position];
}
catch (IndexOutOfRangeException) { throw new InvalidCastException(); }
}
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
position++;
return position < employess.Length;
}
public void Reset()
{
position = -1;
}
}
You can see here that we are implementing methods of the IEnumerator
interface explicitly.
I think this class is self describable. Now we are moving into how to use this concept. Here is some code that uses these classes.
static class Enumerator
{
[STAThread]
static void Main(string[] args)
{
Employee[] list = new Employee[]{
new Employee() { FirstName="Himanshu", LastName="Manjarawala", Age=30},
new Employee(){ FirstName="Hetal", LastName="Sangani", Age=26},
new Employee(){ FirstName="Viral", LastName="Sangani", Age=32},
new Employee(){ FirstName="Rajesh", LastName="Patel", Age=29},
new Employee(){ FirstName="Nehal", LastName="Thakkar", Age=30}
};
var enumerable = new EmployeeCollection(list);
var enumerator = enumerable.GetEnumerator();
while (enumerator.MoveNext())
{
Employee e = enumerator.Current;
Console.WriteLine(e.ToString());
}
}
}
Here, we’ve defined an Array
of our own Employee
class. You can define a List<>
as well. As we know, both are of the System.Collection
type,
so they internally support Enumerable methods. We instantiate our own EmployeeCollection
class and then from there we’ll get our Enumerator object
for the Employee
class using the GetEnumerator()
method and from that object we can iterate over our array members. Hope you like this concept
of the Iterator pattern.