Which types of classes can use foreach
loops?
Actually, strictly speaking, all you need to use foreach
is a public GetEnumerator()
method that returns something with a bool MoveNext()
method and a ? Current {get;}
property. However, the most common meaning of this is "something that implements IEnumerable
/IEnumerable<T>
, returning an IEnumerator
/IEnumerator<T>
.
By implication, this includes anything that implements ICollection
/ICollection<T>
, such as anything like Collection<T>
, List<T>
, arrays (T[]
), etc. So any standard "collection of data" will generally support foreach
.
For proof of the first point, the following works just fine:
using System;
class Foo {
public int Current { get; private set; }
private int step;
public bool MoveNext() {
if (step >= 5) return false;
Current = step++;
return true;
}
}
class Bar {
public Foo GetEnumerator() { return new Foo(); }
}
static class Program {
static void Main() {
Bar bar = new Bar();
foreach (int item in bar) {
Console.WriteLine(item);
}
}
}
How does it work?
A foreach loop like foreach(int i in obj) {...}
kinda equates to:
var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
int i; // C# 5.0
i = tmp.Current;
{...} // your code
}
However, there are variations. For example, if the enumerator (tmp) supports IDisposable
, it is used too (similar to using
).
Note the difference in the placement of the declaration "int i
" inside (C# 5.0) vs. outside (up C# 4.0) the loop. It's important if you use i
in an anonymous method/lambda inside your code-block. But that is another story ;-p