Rafael Romão
Rafael Romão

Reputation: 1798

Why foreach statements accept objects that implement the 'Collection' pattern instead of accept only objects that implement IEnumerable?

Many people ask me why, and I don`t have a good answer for them.

Obviously there is a good reason. Does anyone know it?

I searched here and found this question. It explains how it works, but not why.

Upvotes: 2

Views: 530

Answers (2)

supercat
supercat

Reputation: 81307

There are a couple more advantages to duck-typed foreach versus IEnumerable:

  1. There are some things which satisfy enough of the "IEnumerable" contract to be usable with "foreach", but which don't fully satisfy the contract, especially the ability to repeatedly get independent enumerators. With regard this point, alloing "foreach" to accept either IEnumerator [generic or not] or IEnumerable [likewise] would be an alternative solution.
  2. Although some implementations of IEnumerable.GetEnumerator return a struct that implements IEnumerator, and although this is useful when using duck typing, the behavior can be problematic in some contexts. The fact that foreach uses duck typing allows compilers to have a public GetEnumerator() function return a struct-type enumerator (which does not implement any interface) and have compilers use that, while having IEnumerable.GetEnumerator return a class.

The second advantage can really only be achieved via duck-typing.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503599

Suppose you wanted the equivalent of an IEnumerable<int> but were using C# 1.0. You could implement IEnumerable - but that would require boxing and unboxing on each iteration. Using the sort of duck-typing version of foreach you could get away without any boxing. In many cases the boxing wouldn't actually be that harmful (I tend to find that the performance hit is exaggerated) but it's still inelegant.

I strongly, strongly suspect that if generics had been around in C# 1.0, foreach would have been restricted to IEnumerable<T>.

Upvotes: 11

Related Questions