I suspect the reason this works this way is because `foreach` is a language construct - not a part of the .NET Framework Class Library.
On the other hand, `IEnumerable` is an interface defined in the class library that ships as part of the .NET runtime. Having the foreach construct require implementing IEnumerable will tie the compiler to a specific class definition. So instead, it only looks for a method with that name, which happens to be formalized in the class library in the form of an interface called IEnumerable.
Edit: hm.. but I note that this doesn't work for the using(){} construct.
This requires the object to implement an interface that is convertable to IDisposable instead of just looking for a `Dispose` method.
I always found this somewhat inelegant. I suppose given all the constraints, its OK, but it feels like such a feature (such as the collection initializers) should be based on language constructs, not compiler special cases.
Lucian Wischik gave a really nice talk recently about language design at Microsoft and he indicated that they are trying to do it in that order from now on: determine the feature that's needed, add the necessary plumbing that would allow programmers to implement it, and implement it as a reference implementation.
The big one he doesn't cover is LINQ query syntax. There's a post on my blog ( http://contextfree.livejournal.com ) where I explain why it works this way ...
Edit: hm.. but I note that this doesn't work for the using(){} construct.
This requires the object to implement an interface that is convertable to IDisposable instead of just looking for a `Dispose` method.