Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / May 2008

Tip: Looking for answers? Try searching our database.

IEnumerable objects are essentially arrays, right?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
gnewsgroup - 11 May 2008 21:13 GMT
I've read the msdn doc about IEnumerable. It seems to me that
IEnumerable objects are essentially wrapped-up arrays. It simply gives
us the foreach convenience. Is this correct?
Jon Skeet [C# MVP] - 11 May 2008 21:54 GMT
> I've read the msdn doc about IEnumerable. It seems to me that
> IEnumerable objects are essentially wrapped-up arrays. It simply gives
> us the foreach convenience. Is this correct?

No, not at all.

IEnumerable represents a sequence of items - but unlike arrays:

1) It doesn't provide random access; you basically have to go forwards
(or start again)

2) It's read-only

3) IEnumerable is an *interface* - it can be implemented any way that's
appropriate

4) Arrays are always totally in-memory. IEnumerable implementations can
enumerate anything; for instance, it could enumerate each line in a web
response *as it arrives* without even knowing how long the response is.
Heck, you could enumerate an infinite random number sequence - it's up
to the caller to quit when they want to.

<blatant plug>
See http://www.manning-source.com/books/skeet/Chapter6sample.pdf for
rather more about the iterator pattern.
</blatant plug>

Signature

Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox.com/~skeet   
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com

gnewsgroup - 11 May 2008 22:27 GMT
Jon Skeet [ C# MVP ] wrote:
> > I've read the msdn doc about IEnumerable. It seems to me that
> > IEnumerable objects are essentially wrapped-up arrays. It simply gives
[quoted text clipped - 28 lines]
> Blog: http://www.msmvps.com/jon.skeet
> C# in Depth: http://csharpindepth.com

Thank you. I know IEnumerable is an interface.  I didn't mean
IEnumerable objects and arrays are exactly the same.  I notice that
quite often the constructor of an IEnumerable class takes an array as
the argument, and I think foreach internally makes use of the MoveNext
method. Is it the case that the core of an IEnumerable object is an
array? Thanks.
Pavel Minaev - 11 May 2008 22:44 GMT
> Thank you. I know IEnumerable is an interface.  I didn't mean
> IEnumerable objects and arrays are exactly the same.  I notice that
> quite often the constructor of an IEnumerable class takes an array as
> the argument, and I think foreach internally makes use of the MoveNext
> method. Is it the case that the core of an IEnumerable object is an
> array? Thanks.

No, it is not. It all depends on which particular implementation of
IEnumerable you take. E.g. array itself is IEnumerable. List<T> is
IEnumerable and also wraps an array. But LinkedList<T> is IEnumerable,
and is not an array, nor does it behave like one (you can't access
elements by index). Another example would be method Enumerable.Range()
in .NET 3.5 - you give it a lower and an upper bound, and returns an
implementation of IEnumerable that produces numbers in that range. It
would be implemented something like this:

class Range : IEnumerable<int>
{
private int lowerBound, upperBound;

 public Range(int lowerBound, int upperBound)
 {
   this.lowerBound = lowerBound;
   this.upperBound = upperBound;
 }

 public IEnumerator<int> GetEnumerator()
 {
   for (int i = lowerBound; i <= upperBound; ++i)
   {
     yield return i;
   }
 }
}

As you can notice, there are no arrays here at all...

The concept that IEnumerable represents is actually a "sequence" (a
finite or an infinite one - noone says that MoveNext() ever has to
return false!). "Array" is a more specific concept - to quote
Wikipedia, "In computer science an array is a data structure
consisting of a group of elements that are accessed by indexing. In
most programming languages each element has the same data type and the
array occupies a contiguous area of storage.". Obviously, any array is
also a sequence, but not every sequence is an array or even array-like
(since not every sequence can be indexed, and some - e.g.
Dictionary<T> and HashSet<T> - do not even have any specific ordering).
gnewsgroup - 12 May 2008 00:10 GMT
> > Thank you. I know IEnumerable is an interface.  I didn't mean
> > IEnumerable objects and arrays are exactly the same.  I notice that
[quoted text clipped - 44 lines]
> (since not every sequence can be indexed, and some - e.g.
> Dictionary<T> and HashSet<T> - do not even have any specific ordering).

Thank you very much.  I think it is much clearer to me.  The range
example you gave is actually a question I have which I am planning on
following up in this thread, although really the example I am
interested in is the Power example as shown  at
http://msdn.microsoft.com/en-us/library/9k7k7cf0(VS.80).aspx . You'll
notice that it is very similar to your Range example.

The question I have about the Power example is:

The while loop:

while (counter++ < exponent)
{
     result = result * number;
     yield return result;
}

indicates that block likely will execute multiple times.  The question
is, where does the result go?  Note that result is declared as an
int.  Is it converting the int result to IEnumerable and pad the
result to this IEnumberabilized result?  This is where I don't
understand.  I hope that I have made my question clear.  Thank you.
Peter Duniho - 12 May 2008 00:51 GMT
> [...]
> The question I have about the Power example is:
[quoted text clipped - 9 lines]
> indicates that block likely will execute multiple times.  The question
> is, where does the result go?

It's returned by IEnumerator.Current, where the IEnumerator is "returned"  
(sort of) by the method in question, indirectly through the IEnumerable in  
that particular example.

> Note that result is declared as an
> int.  Is it converting the int result to IEnumerable and pad the
> result to this IEnumberabilized result?  This is where I don't
> understand.  I hope that I have made my question clear.  Thank you.

To answer your direct question: no, the int is not converted to  
IEnumerable.

It is a little confusing, because the compiler is hiding so much from  
you.  But a method that contains a "yield" statement is treated  
differently from normal methods.  The compiler essentially creates a  
hidden class that implements the enumeration described by the method, via  
the IEnumerable interface in this example.

This hidden class manages the current state.  When you call the method,  
all that's returned is a reference to the IEnumerable (or whatever type  
was declared for the iterator) that the compiler created.  Something using  
IEnumerable (for example, a "foreach" loop) calls GetEnumerator() to get  
the IEnumerator interface implemented by the hidden class.  The compiler  
has built the hidden class so that when you call IEnumerator.MoveNext(),  
it executes the code in the method that you wrote until it hits the  
"yield" statement.  At that point, the return value is stored and the  
MoveNext() implementation returns.  Calling IEnumerator.Current retrieves  
the stored value.

For the non-generic IEnumerable, the IEnumerator returned is of course a  
non-generic implementation and so Current always returns an Object.  When  
the "yield" statement returns an int, this is boxed automatically.  It's  
then unboxed by whatever code is actually using the  
IEnumerable/IEnumerator.

If you implement the generic IEnumerable<T> interface, then the value  
returned by IEnumerator<T>.Current will be the same type as that returned  
by the "yield" statement, without any boxing.

But in neither case does the return value associated with the "yield"  
statement have anything directly to do with the declared return type of  
the method.  An iterator method must return IEnumerable, IEnumerator, or  
the generic versions of those interfaces.  The type of the "yield return"  
statement determines the type of the data returned by the Current property  
of the relevant enumerator interface.  The _presence_ of a "yield"  
statement requires that enumerable/enumerator return value, and the type  
actually returned by the "yield" statement determines what Current returns  
(boxed, if necessary).

For more information, if you haven't already you may want to read the  
description of C# iterators:  
http://msdn.microsoft.com/en-us/library/dscyy5s0.aspx (there's a link to  
that document from the doc page for "yield" that you mentioned)

Pete
gnewsgroup - 12 May 2008 04:02 GMT
On May 11, 7:51 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:

> > [...]
> > The question I have about the Power example is:
[quoted text clipped - 64 lines]
>
> Pete

Thank you Peter for the detailed explanation.  I think things are
getting much clearer now.  The iterator article, albeit short, is very
helpful.  I will re-read your explanation and practice a little to
thoroughly understand this whole thing.  Thanks again.
Marc Gravell - 12 May 2008 08:17 GMT
If it helps, I answered a very similar question recently here:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3274206&SiteID=1

In particular it shows a lot of things a compiler normally hides from
you, and demonstrates an infinite sequence (Fibonacci).

Jon's book has more information on a lot of the details - and if ch 6 is
free, go get it!

Marc
gnewsgroup - 12 May 2008 14:35 GMT
> If it helps, I answered a very similar question recently here:http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3274206&SiteID=1
>
[quoted text clipped - 5 lines]
>
> Marc

Thank you very much.  I have downloaded sample chapter 6 of Mr.
Skeet's book.  I hope it'll de-confuse me on this issue.
Jon Skeet [C# MVP] - 12 May 2008 19:54 GMT
> Thank you very much.  I have downloaded sample chapter 6 of Mr.
> Skeet's book.  I hope it'll de-confuse me on this issue.

Cool - do post again if it doesn't help though, as much for my benefit
(in terms of improving future editions of the books) as for yours!

Signature

Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox.com/~skeet   
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com

Tim Jarvis - 12 May 2008 00:28 GMT
> > <blatant plug>
> > See http://www.manning-source.com/books/skeet/Chapter6sample.pdf for
> > rather more about the iterator pattern.

> Thank you. I know IEnumerable is an interface.  I didn't mean
> IEnumerable objects and arrays are exactly the same.  I notice that
> quite often the constructor of an IEnumerable class takes an array as
> the argument, and I think foreach internally makes use of the MoveNext
> method. Is it the case that the core of an IEnumerable object is an
> array? Thanks.

The thing about an Interface is that there is no requirement that the
underlying implementation is a specific class, thats the beauty of
interfaces they provide polymorphic behaviour /accross/ class
heirachy's. Its simply a contract that the underlying implementation
will provide a (in this case) GetEnumerator method, it so happens that
system.array does, but so do many other classes. So I guess the exact
answer to your question is Sometimes the "core" is an array, sometimes
its not.

Definitely have a read of Jon's chapter, he explains in quite some
detail what's going on.

Regards Tim.

--
Jon Skeet [C# MVP] - 12 May 2008 06:21 GMT
> Thank you. I know IEnumerable is an interface.  I didn't mean
> IEnumerable objects and arrays are exactly the same.  I notice that
> quite often the constructor of an IEnumerable class takes an array as
> the argument, and I think foreach internally makes use of the MoveNext
> method. Is it the case that the core of an IEnumerable object is an
> array? Thanks.

The core of an IEnumerable object is whatever that implementation wants
to use. Sometimes it will be an array, but it certainly doesn't have to
be.

Signature

Jon Skeet - <skeet@pobox.com>
Web site: http://www.pobox.com/~skeet   
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com

gnewsgroup - 12 May 2008 14:40 GMT
> > Thank you. I know IEnumerable is an interface.  I didn't mean
> > IEnumerable objects and arrays are exactly the same.  I notice that
[quoted text clipped - 12 lines]
> Blog:http://www.msmvps.com/jon.skeet
> C# in Depth:http://csharpindepth.com

Thank you, Jon.  I was misled by the MSDN People example at
http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx,
which takes an array of Person.  I will read Ch 6 of your in-depth
book.  Thank you.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.