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