471,350 Members | 1,770 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,350 software developers and data experts.

Question about IEnumerable and Interface Signatures

In the code below from MSDN

How do the PeopleEnum methods ever get called?

foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);

What is going on behind the scenes in the foreach?

Also, I could not find where the interface signatures were for the
IEnumerable and IEnumerator. How did they know what methods they were
required to use from the interface signature. I looked them up on
MSDN, but didn't see any references to GetEnumerator or MoveNext.
Just this type explanation:

[ComVisibleAttribute(true)]
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator

http://msdn.microsoft.com/en-us/libr...le(VS.80).aspx

Thanks.

---
using System;
using System.Collections;

public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}

public string firstName;
public string lastName;
}

public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];

for (int i = 0; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
}

public IEnumerator GetEnumerator()
{
return new PeopleEnum(_people);
}
}

public class PeopleEnum : IEnumerator
{
public Person[] _people;

// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;

public PeopleEnum(Person[] list)
{
_people = list;
}

public bool MoveNext()
{
position++;
return (position < _people.Length);
}

public void Reset()
{
position = -1;
}

public object Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}

class App
{
static void Main()
{
Person[] peopleArray = new Person[3]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
};

People peopleList = new People(peopleArray);
foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);

}
}

/* This code produces output similar to the following:
*
* John Smith
* Jim Johnson
* Sue Rabon
*
*/
Jun 27 '08 #1
4 1638
On Jun 12, 5:01 pm, jmDesktop <needin4mat...@gmail.comwrote:
In the code below from MSDN

How do the PeopleEnum methods ever get called?

foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);

What is going on behind the scenes in the foreach?
foreach calls GetEnumerator() on the IEnumerable to get an
IEnumerator, then calls MoveNext() and Current on the IEnumerator,
executing the body of the loop each time, until MoveNext() returns
false or the body of the foreach loop exits early somehow (break/
return/exception).

It then (irrespective of whether it reached the end or not) checks
whether or not the IEnumerator implements IDisposable, and calls
Dispose if so. (The generic IEnumerator<Tinterface extends
IDisposable, so if there's a generic IEnumerable<Tthe compiler
doesn't need to perform an execution-time check here - it just calls
Dispose.)
Also, I could not find where the interface signatures were for the
IEnumerable and IEnumerator. How did they know what methods they were
required to use from the interface signature. I looked them up on
MSDN, but didn't see any references to GetEnumerator or MoveNext.
The interfaces IEnumerable and IEnumerator are both defined in the
System.Collections namespace, and the methods within them are
documented in MSDN in the normal way. The generic forms are in the
System.Collections.Generic namespace.

In fact, the C# compiler can use foreach without implementing
IEnumerable and IEnumerator at all - but it's extremely rare.

Jon
Jun 27 '08 #2
Rather that explaining here what happens, I would suggest you compile the
code and open the assembly in ildasm.exe to exactly see what the compiler
does behind the scenes. Thats the best way IMO to know.

Sujeet

"jmDesktop" wrote:
In the code below from MSDN

How do the PeopleEnum methods ever get called?

foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);

What is going on behind the scenes in the foreach?

Also, I could not find where the interface signatures were for the
IEnumerable and IEnumerator. How did they know what methods they were
required to use from the interface signature. I looked them up on
MSDN, but didn't see any references to GetEnumerator or MoveNext.
Just this type explanation:

[ComVisibleAttribute(true)]
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator

http://msdn.microsoft.com/en-us/libr...le(VS.80).aspx

Thanks.

---
using System;
using System.Collections;

public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}

public string firstName;
public string lastName;
}

public class People : IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length];

for (int i = 0; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
}

public IEnumerator GetEnumerator()
{
return new PeopleEnum(_people);
}
}

public class PeopleEnum : IEnumerator
{
public Person[] _people;

// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;

public PeopleEnum(Person[] list)
{
_people = list;
}

public bool MoveNext()
{
position++;
return (position < _people.Length);
}

public void Reset()
{
position = -1;
}

public object Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}

class App
{
static void Main()
{
Person[] peopleArray = new Person[3]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
};

People peopleList = new People(peopleArray);
foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);

}
}

/* This code produces output similar to the following:
*
* John Smith
* Jim Johnson
* Sue Rabon
*
*/
Jun 27 '08 #3
Adding to what John said, specifically for foreach statement the 'peopleList'
type does not have to implement IEnumearble. It can also just have a method
GetEnumerator() that returns a type Person that has a public instance
'MoveNext()' method that returns a bool and a public instance property
'Current' that returns the type 'Person'

But IMO implementing IEnumerable explicitly is more cleaner and easy to read.

Sujeet

"Jon Skeet [C# MVP]" wrote:
On Jun 12, 5:01 pm, jmDesktop <needin4mat...@gmail.comwrote:
In the code below from MSDN

How do the PeopleEnum methods ever get called?

foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);

What is going on behind the scenes in the foreach?

foreach calls GetEnumerator() on the IEnumerable to get an
IEnumerator, then calls MoveNext() and Current on the IEnumerator,
executing the body of the loop each time, until MoveNext() returns
false or the body of the foreach loop exits early somehow (break/
return/exception).

It then (irrespective of whether it reached the end or not) checks
whether or not the IEnumerator implements IDisposable, and calls
Dispose if so. (The generic IEnumerator<Tinterface extends
IDisposable, so if there's a generic IEnumerable<Tthe compiler
doesn't need to perform an execution-time check here - it just calls
Dispose.)
Also, I could not find where the interface signatures were for the
IEnumerable and IEnumerator. How did they know what methods they were
required to use from the interface signature. I looked them up on
MSDN, but didn't see any references to GetEnumerator or MoveNext.

The interfaces IEnumerable and IEnumerator are both defined in the
System.Collections namespace, and the methods within them are
documented in MSDN in the normal way. The generic forms are in the
System.Collections.Generic namespace.

In fact, the C# compiler can use foreach without implementing
IEnumerable and IEnumerator at all - but it's extremely rare.

Jon
Jun 27 '08 #4
Sujeet <Su****@discussions.microsoft.comwrote:
Adding to what John said, specifically for foreach statement the 'peopleList'
type does not have to implement IEnumearble. It can also just have a method
GetEnumerator() that returns a type Person that has a public instance
'MoveNext()' method that returns a bool and a public instance property
'Current' that returns the type 'Person'

But IMO implementing IEnumerable explicitly is more cleaner and easy to read.
Agreed - although I'd implement IEnumerable<Personand do it with an
iterator block :)

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jun 27 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Bob Rundle | last post: by
2 posts views Thread by Peter Rilling | last post: by
10 posts views Thread by jcc | last post: by
3 posts views Thread by KH | last post: by
2 posts views Thread by =?Utf-8?B?a2VubmV0aEBub3NwYW0ubm9zcGFt?= | last post: by
1 post views Thread by Larry | last post: by
1 post views Thread by =?Utf-8?B?UElFQkFMRA==?= | last post: by
reply views Thread by XIAOLAOHU | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.