Mike Stall has written a great article on how the foreach keyword actually works.
“Do you know how the following C# code compiles?
foreach (int i in c) { Console.WriteLine(i); }
In addition to the obvious branching opcodes, this can also emit try/finally, a call to IDisposable, unboxing opcodes.”
For more please see his post