sequence of foreach

  • Thread starter Thread starter Wilfried Mestdagh
  • Start date Start date
W

Wilfried Mestdagh

Hi,

does foreach guarantees the sequence order starting from index 0 ?
 
Wilfried,

foreach uses an IEnumerator returned by the collection. So it depends
on how the IEnumerator is implemented and who provided it.

In the case of an array, ArrayList, or List<T> then yes. The order is
defined by the index in the collection.

Which collection are you referring to?

Brian
 
No, I don't think so. You could for example do:

System.Object[] list = new System.Object[3] {2, 3, "This is printed."};
foreach (string item in list)
System.Console.WriteLine(item.ToString());

The foreach loop (I think) only picks up the string at index 2, so it
doesn't start at 0.


However, as far as I've seen (and counted on in several applications),
it does seem the foreach loops through the list/array from index 0 to
the end. So it seems items with lower indexes tend to come first.
 
No, but yes. Ish.

Iterators can legitimately return in any order... for instance, you can get
iterators whose entire purpose is to iterate backwards over a set of date.
However for common lists, collections, arrays etc it does go forwards.

Note that dictionaries and hashtables do not guarantee to preserve order at
the point of insertion.

Marc
 
Actually, that will raise an invalid cast exception. foreach does not skip
badly typed data. However, I believe that LINQ (3.0) introduces this
capability into the standard queries (via the OfType operator).

Marc
 
Hi Brian,

DataTable.Rows
foreach (DataRow row in dataTable.Rows)
...

It seems to come in the right sequence in a few experiments I have done,
but wanted to be sure.

--
rgds, Wilfried [MapPoint MVP]
http://www.mestdagh.biz

Brian said:
Wilfried,

foreach uses an IEnumerator returned by the collection. So it depends
on how the IEnumerator is implemented and who provided it.

In the case of an array, ArrayList, or List<T> then yes. The order is
defined by the index in the collection.

Which collection are you referring to?

Brian
 
Hi Marc,

So if I understeand well, it is best if not sure to do a small
testproject to see how it is implemented ? And the direction per
collection type will always be the same ?
 
Also an enumerator may not have any index and just yield results until some
condition. For example, you could return and enumerator on a Producer class
that somehow produces objects and just foreach over it. Standard collection
enumerators will start at 0 and go till end in order. So it all depends on
the implementation of the IEnumerator. For example, you could step, or go
in reverse, etc.

--
William Stacey [C# MVP]

| Hi,
|
| does foreach guarantees the sequence order starting from index 0 ?
|
| --
| rgds, Wilfried [MapPoint MVP]
| http://www.mestdagh.biz
 
Actually, if in doubt I'd just RTM. Test cases aren't proof positive:
I've seen someone argue that Dictionary preserves sort order because a
test case says so. Simple fact is that Dictionary *sometimes* preserves
sort order, either by conincidence or small data sets... who knows.

As stated, most "standard" (if that term apples) inbuilt sets iterate
strictly forwards... but you can normally check, for instance
Array.GetEnumerator() [which underpins the foreach compiler support]:

http://msdn2.microsoft.com/en-us/library/system.array.getenumerator.aspx
<quote>
Initially, the enumerator is positioned before the first element in the
collection. Reset also brings the enumerator back to this position.
<snip/>
Current returns the same object until either MoveNext or Reset is
called. MoveNext sets Current to the next element.
<snip/>
If MoveNext passes the end of the collection, the enumerator is
positioned after the last element in the collection and MoveNext
returns false.
</quote>

This translates as "foreach goes from 0 to Length-1"

However, as pointed out by William, not all enumerators do this. You
can define for instance infinite enumerators (fibonacci numbers
perhaps? random numbers? annoying paperclip messages?), or a single set
can support multiple enumerators (via separate accessor properties /
methods), such as .GetEnumerator(), ReverseOrder.GetEnumerator(),
AlphabeticalOrder.GetEnumerator(), whatever. These would have to be
defined by whatever class implements them, of course ;-p

Marc
 
Hi Marc and others,

Thank you for good explanation. I have used it now in:
DataTable.Rows
foreach (DataRow row in dataTable.Rows)

Is this one OK ?
 
yup

And it is a reasonable default assumption for most containers... really I
think everyone was just trying to make you aware that it isn't a guarantee
;-p

Happy coding,

Marc
 

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

Back
Top