I have a foreach
loop that needs converting to a for
or while
loop. My loop looks like this:
foreach (Item item in Items)
{
// some stuff
}
What is the equivalent for
or while
loop?
I think I need to use GetEnumerator
to get an IEnumerator<Item>
, but I don't know how to use it properly. Items
isn't a list, otherwise I'd use indexing.
In the simplest case(no disposing etc.) you can use:
var enumerator = Items.GetEnumerator();// `var` to take advantage of more specific return type
while(enumerator.MoveNext())
{
Item item = enumerator.Current;
...
}
For the exact rules check the C# specification 8.8.4 The foreach statement.
A foreach statement of the form
foreach (V v in x) embedded-statement
is then expanded to:
{ E e = ((C)(x)).GetEnumerator(); try { V v; while (e.MoveNext()) { v = (V)(T)e.Current; embedded-statement } } finally { … // Dispose e }
}
(Quoted from the C# Language Specification Version 4.0)
The types using here are: "a collection type C
, enumerator type E
and element type T
". E
is the return type of GetEnumerator
, and not necessarily IEnumerator<V>
since foreach
uses duck typing. The spec also describes a number of corner cases and how to infer these types, but those details are probably not relevant here.
In C# 5 the declaration of v
will be moved into the while
loop to get more intuitive closure semantics.
If you're going to use a for
loop, it generally means there's some way of quickly accessing the n-th item (usually an indexer).
for(int i = 0; i < Items.Count; i++)
{
Item item = Items[i]; //or Items.Get(i) or whatever method is relevant.
//...
}
If you're just going to access the iterator, you usually just want to use a foreach
loop. If, however, you can't, this is usually the model that makes sense:
using(IEnumerator<Item> iterator = Items.GetEnumerator())
while(iterator.MoveNext())
{
Item item = iterator.Current;
//do stuff
}
you could, technically, do this in a for
loop, but it would be harder because the construct just doesn't align well with this format. If you were to discuss the reason that you can't use a foreach
loop we may be able to help you find the best solution, whether or not that involves using a for
loop or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With