About iterator and yield

T

Tony Johansson

Hello!

In C# 2.0 has iterator been added and this posting is about that.

Here is a method that has implemented GetEnumerator without using iterator
IEnumerator<T> IEnumerator.GetEnumerator()
{
return new TreeEnumerator<T>(this);
}
There is also another class called TreeEnumerator which has implemented the
IEnumerator<T> interface.
This is easy to understand.

Below I have a class called BasicCollection<T> which use iterator.

Now to my first question: This method:
IEnumerator<T> IEnumearble<T>.GetEnumerator()
{
for (int i = 0; i<data.Count; i++) yield return data;
}
implement the IEnumarable<T> interface and it return an
IEnumerator<T> according to the return type but it doesn't look like that.
Can somebody explain that ?

I test this by writing this code and it writes them out in the same order
that I inserted them into FillList which is correct.
BasicCollection<string> bc = new BasicCollection<string>();
bc.FillList("Twas", "brillig", "and", "the", "slithy", "toves");
foreach(string word in bc);
Console.WriteLine(word);

Assume I want to write them out in the Reverse sequence I can then write
this method which has been found in a book
public IEnumerable<T> Reverse()
{
get
{
for ( int i = data.Count -1 ; i>= 0; i--)
yield return data;
}
}

To test this I can write this test code and it do writes then in the revers
sequence which in correct.
BasicCollection<string> bc = new BasicCollection<string>();
bc.FillList("Twas", "brillig", "and", "the", "slithy", "toves");
foreach(string word in bc.Reverse);
Console.WriteLine(word);

Now to my second question:
I can't understand this. In the first method that used iterator that was
called GetEnumerator it said yield return data;
and this caused a IEnumerator<T> to be returned.
In the second example that uses iterator it said yield return data; and
now it return an IEnumerable<T>
So the same statement will return different interface types.

class BasicCollection<T> : IEnumerable<T>
{
private List<T> data = new List<T>();

public void FillList(params T [] items)
{
for (int i = 0; i < items.Length; i++)
data.Add(items);
}

IEnumerator<T> IEnumearble<T>.GetEnumerator()
{
for (int i = 0; i<data.Count; i++) yield return data;
}
}

//Tony
 
J

Jon Skeet [C# MVP]

In C# 2.0 has iterator been added and this posting is about that.

Here is a method that has implemented GetEnumerator without using iterator
IEnumerator<T> IEnumerator.GetEnumerator()
{
return new TreeEnumerator<T>(this);}

There is also another class called TreeEnumerator which has implemented the
IEnumerator<T> interface.
This is easy to understand.

Below I have a class called BasicCollection<T> which use iterator.

Now to my first question: This method:
IEnumerator<T> IEnumearble<T>.GetEnumerator()
{
for (int i = 0; i<data.Count; i++) yield return data;}

implement the IEnumarable<T> interface and it return an
IEnumerator<T> according to the return type but it doesn't look like that.
Can somebody explain that ?


Well, that's basically what iterator blocks are all about. Your code
doesn't explicitly return the iterator, it returns the data, one datum
at a time. The compiler builds a state machine to handle the
iteration.

Now to my second question:
I can't understand this. In the first method that used iterator that was
called GetEnumerator it said yield return data;
and this caused a IEnumerator<T> to be returned.
In the second example that uses iterator it said yield return data; and
now it return an IEnumerable<T>


Iterator blocks apply to members returning *either* an IEnumerator
*or* an IEnumerable. Both work. The same compiler magic applies to
both ways of doing things.

See this article for more about iterator blocks (and LINQ):

http://www.eggheadcafe.com/tutorial...94-3bde8a5f2d50/iterators-iterator-block.aspx

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top