Suppose from the above employee collection if I need to
iterate into all the employees whose age is greater than 50 using for-each
statement and display their name. To achieve this I need to implement a custom
enumerator that gives me the employees with age greater than 50.
In the coming sections, I will take you through the traditional implementation that will implement
IEnumerable, IEnumerator interfaces called SeniorEmployeeEnumerator, means I need
to implement MoveNext(),Reset() and Current of IEnumerator and GetEnumerator() of
IEnumerable interface in SeniorEmployeeEnumerator class explicitly to iterate the collection.
The syntax of IEnumerator<T> is,
public interface IEnumerator<T> : IDisposable,
IEnumerator
The syntax of IEnumerable<T> interface is,
public interface IEnumerable<T> : IEnumerable
Here is the implementation of SeniorEmployeeEnumerator object.
public class SeniorEmployeeEnumerator :
IEnumerable<Employee>,
IEnumerator<Employee>
{
List<Employee> list = new List<Employee>();
private Int32 _inUseIndex = 0;
private Int32 _moveNextStartIndex = 0;
private int MoveNextStartIndex
{
get { return _moveNextStartIndex; }
set { _moveNextStartIndex = value; }
}
private int InUseIndex
{
get { return _inUseIndex; }
set { _inUseIndex = value; }
}
#region IEnumerator Members
public bool MoveNext()
{
bool returnFlag = false;
for (Int32 index = MoveNextStartIndex; index <= list.Count - 1; index++)
{
if (list[index].Age > 50)
{
InUseIndex = index;
MoveNextStartIndex = index + 1;
returnFlag = true;
break;
}
}
return returnFlag;
}
public void Reset()
{
_inUseIndex = 0;
_moveNextStartIndex = 0;
}
public Employee Current
{
get
{
if ((InUseIndex < 0) | (InUseIndex >= list.Count))
{
throw new InvalidOperationException("The enumerator is positioned outside
the bounds of the collection elements.");
}
return list[InUseIndex];
}
}
object IEnumerator.Current
{
get
{
return Current;
}
}
#endregion
void IDisposable.Dispose()
{
}
public SeniorEmployeeEnumerator(List<Employee> emplist)
{
list = emplist;
}
#region IEnumerable Members
public IEnumerator<Employee> GetEnumerator()
{
return this;
}
IEnumerator IEnumerable.GetEnumerator()
{
return (GetEnumerator());
}
#endregion
}
To get the enumerator that iterates through the employees
collection with age greater than 50 we need to add a function in
EmployeeCollection that return back the enumerartor,
public SeniorEmployeeEnumerator
GetSeniorEmployeeEnumerator()
{
SeniorEmployeeEnumerator enume = new SeniorEmployeeEnumerator(_list);
return enume;
}
So totally we have 3 objects,
Employee – BO or Entity
EmployeeCollection – Collection of Employee BO
SeniorEmployeeEnumerator - Custom enumerator for iterating
the collection.
Usage:
List<Employee> emplist = new List<Employee>();
Employee emp1 = new Employee();
emp1.Name = "Fatima";
emp1.Age = 57;
emplist.Add(emp1);
Employee emp2 = new Employee();
emp2.Name = "Evangeline";
emp2.Age = 52;
emplist.Add(emp2);
Employee emp3 = new Employee();
emp3.Name = "Damien";
emp3.Age =49;
emplist.Add(emp3);
Employee emp4 = new Employee();
emp4.Name = "Cameroon";
emp4.Age = 55;
emplist.Add(emp4);
Employee emp5 = new Employee();
emp5.Name = "Babu";
emp5.Age = 24;
emplist.Add(emp5);
EmployeeCollection empcoll = new EmployeeCollection();
empcoll.Employees = emplist;
foreach (Employee emp in
empcoll.GetSeniorEmployeeEnumerator())
{
Response.Write(emp.Name + " " + emp.Age +
"");
}
The output will be,
OUTPUT:
Fatima 57
Evangeline 52
Cameroon 55
yield keyword:
The above custom enumerator can be implemented easily with the
use of yield keyword. yield keyword is used in GetEnumerator() method of
IEnumerable interface and we don’t need to explicitly implement the
MoveNext(),Reset() and Current of IEnumerator interface.
So our SeniorEmployeeEnumerator class will look like,
public class SeniorEmployeeEnumerator :
IEnumerable<Employee>
{
List<Employee> list = new List<Employee>();
public SeniorEmployeeEnumerator(List<Employee> emplist)
{
list = emplist;
}
public IEnumerator<Employee> GetEnumerator()
{
for (int i = 0; i < list.Count; i++)
{
if (list[i].Age > 50)
{
yield return list[i];
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return (GetEnumerator());
}
}
Again the output will be,
OUTPUT:
Fatima 57
Evangeline 52
Cameroon 55
|