There are many reasons. People don’t implement it properly. foreach uses duck typing which does not require one to implement IEnumerable/IEnumerator. But people always go ahead and implement them with "virtual" functions and properties. Consider the performance hit when you are recursively iterating over all the files in a drive.
foreach also requires that collection be not modified during enumeration, yet people still do these kinds of things
foreach( Transaction transaction in transactions )
transactions.Remove( transaction );