Background
I have been seeing quite a number of posts in various discussion boards regarding ‘how to implement iterative access in a custom collection?’. Personally, for newbies, it was an alien step to appreciate the implementation of iterative access for their custom collection even though we have literatures and proven examples. This was the notion of writing an article on IEnumerable
, IEnumerator
interfaces, which facilitates the iterative access in a custom collection along with a well articulated graph and code sample.
Introduction
Unlike C++, .NET Framework facilitates accessing individual elements in the custom collection while implementing IEnumerable
and IEnumerator
interfaces. For example, it is a hassle free job to access types collected in an ArrayList
. This had been eased by ArrayList
class while implementing IEnumerable
and IEnumerator
interfaces.
Before continuing, let me explain the structure, members of the IEnumerable
, IEnumerator
interfaces. The IEnumerable
interface contains an abstract member function called GetEnumerator()
and return an interface IEnumerator
on any success call. This IEnumerator
interface will allow us to iterate through any custom collection.
Note: IEnumerator
interface is meant to be used as accessors and is not helpful to make any changes in the collection or elements of the collection.
Presumably, any element in a collection can be retrieved through its index property. But instead of element index, the IEnumerator
provides two abstract methods and a property to pull a particular element in a collection. And they are Reset()
, MoveNext()
and Current
.
See the figure. This is how it works.
IEnumerator GetEnumerator()
The signature of GetEnumerator()
is as follows:
public IEnumerator GetEnumerator()
{
return(IEnumerator)this;
}
Members of IEnumerator Interface
Reset(), MoveNext(), Current()
The signature of IEnumerator
members is as follows:
void Reset()
bool MoveNext()
object Current
Refer to the figure which depicts three object instances in the custom collection.
The void Reset()
method returns a void
type and helps you to position the pointer just before the start point. Refer to the figure where I have three instances and the pointer is in the empty position. This reset
method will also help you to reset the iteration pointer anywhere from the start position. For example, you are in the second instance and need to start from first. In addition to all, the reset
method has to be called after any successive addition, deletion of elements in the collection.
public void Reset()
{
length=slist.Count;
current=-1;
}
The bool MoveNext()
method will help you to position the location of the required element in the collection while sending a flag value. And its objective is to inform the caller whether the current position holds any value or not. If it has, then MoveNext
will return true
or return false
in case there is no value. In addition, the MoveNext
will help you to position the first element in the collection after calling the reset
method.
public bool MoveNext()
{
return(++current<length);
}
The object Current
property of IEnumerator
interface will return an individual element of a given collection. This property is used to return an element in the collection by using the specified location pointer.
I.e. If you want to iterate through the collection, you need to call the MoveNext()
method just before the Current
. Otherwise, it will return the same element that the current
property previously returns as output. In addition, if you are trying to enumerate for the first time, then you need to call methods and properties in this hierarchy: Reset()
- > MoveNext ()
-> Current
.
public object Current
{
get
{
return(slist[current]);
}
}
Personally, I feel the code which is available along with the article is explanatory enough to give a clear picture for further tunings.
static void Main()
{
Iterator It=new Iterator();
foreach(MyClass MY in It)
{
Console.WriteLine("Name : "+MY.Name.ToString());
Console.WriteLine("Age : "+MY.Age.ToString());
}
}
The aforementioned code is a part in my first example and tries to access the individual elements without implementing the required interfaces. But this code will fail to compile and the message is:
foreach statement cannot operate on variables of type 'CustomCollection.Iterator'
because 'CustomCollection.Iterator' does not contain a definition
for 'GetEnumerator', or it is inaccessible
I address the above compilation error in the second example while implementing IEnumearble
, IEnumerator
interfaces.
public void Reset()
{
Cnt=-1;
}
public bool MoveNext()
{
return (++ Cnt < ClassArray.Length);
}
public object Current
{
get
{
return ClassArray[Cnt];
}
}
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
See the downloads at the top of this article for the source code.
History
- 9th September, 2004: Initial post
- 17th July, 2008: Article updated
He is a certified professional in both MCPD and MCTS. He is a mathematics graduate with masters in computer science.He was born and bred in India and happen to spend some time in Europe.