How is foreach implemented in C#?

Jamie Dixon picture Jamie Dixon · Jun 24, 2012 · Viewed 10.8k times · Source

How exactly is foreach implemented in C#?

I imagine a part of it looking like:

var enumerator = TInput.GetEnumerator();
while(enumerator.MoveNext())
{
  // do some stuff here
}

However I'm unsure what's really going on. What methodology is used for returning enumerator.Current for each cycle? Does it return [for each cycle] or does it take an anonymous function or something to execute the body of foreach?

Answer

Jon Skeet picture Jon Skeet · Jun 24, 2012

It doesn't use an anonymous function, no. Basically the compiler converts the code into something broadly equivalent to the while loop you've shown here.

foreach isn't a function call - it's built-into the language itself, just like for loops and while loops. There's no need for it to return anything or "take" a function of any kind.

Note that foreach has a few interesting wrinkles:

  • When iterating over an array (known at compile-time) the compiler can use a loop counter and compare with the length of the array instead of using an IEnumerator
  • foreach will dispose of the iterator at the end; that's simple for IEnumerator<T> which extends IDisposable, but as IEnumerator doesn't, the compiler inserts a check to test at execution time whether the iterator implements IDisposable
  • You can iterate over types which don't implement IEnumerable or IEnumerable<T>, so long as you have an applicable GetEnumerator() method which returns a type with suitable Current and MoveNext() members. As noted in comments, a type can also implement IEnumerable or IEnumerable<T> explicitly, but have a public GetEnumerator() method which returns a type other than IEnumerator/IEnumerator<T>. See List<T>.GetEnumerator() for an example - this avoids creating a reference type object unnecessarily in many cases.

See section 8.8.4 of the C# 4 spec for more information.