472,954 Members | 2,156 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,954 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 1702
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Bob Rundle | last post by:
I'm trying to serialize a class with XmlSerializer. This class implements the IEnumerable interface. I implemented the IEnumerable interface for reasons other than Xml serialization. However I...
4
by: emma middlebrook | last post by:
Hi Straight to the point - I don't understand why System.Array derives from IList (given the methods/properties actually on IList). When designing an interface you specify a contract. Deriving...
2
by: Peter Rilling | last post by:
A design pattern question. As you know, an enumerator in .NET is broken into two interface (IEnumerable and IEnumerator). Is there a benefit in having two interfaces? Why not just have the...
10
by: jcc | last post by:
Hi guys, I'm a newbie to C#. My Visual Studio 2005 failed to compile the following code with error as 'HelloWorld.A' does not implement interface member...
3
by: KH | last post by:
I can't seem to figure this one out... I've searched MSDN and Goog, and made my best guesses to no avail,, so help would be much appreciated! public ref class T sealed : public...
2
by: =?Utf-8?B?a2VubmV0aEBub3NwYW0ubm9zcGFt?= | last post by:
When creating multiple iterators, the original is defined as returning IEnumerator, ie public IEnumerator GetEnumerator() { yield x; ...} whereas the additional ones are defined as returning...
1
by: Larry | last post by:
I checked definition of class CollectionBase public abstract class CollectionBase : IList, ICollection, IEnumerable, it implements 3 interface IList, ICollection and IEnumerable. I found...
1
by: =?Utf-8?B?UElFQkFMRA==?= | last post by:
Something I found surprising this week involves the IEnumerable<Tinterface. I have a class that I wrote a couple of years ago which implements the IEnumerable interface. This week I realized it...
20
by: -- | last post by:
Imagine I have a class TypeX and a class TypeY that inherts TypeX. public class typeX { .... } public class typeY : typeX { ....
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
1
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

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.