Imagine the following code:
class foreach_convert
{
public static void method2()
{
List<IComparable> x = new List<IComparable>();
x.Add(5);
foreach (string s in x)
{
//InvalidCastException in runtime
}
}
}
I wonder, why is this foreach behavior so… not C#-like?
What happens here is an implicit cast to a subclass, which is error-prone and seems to be banned in every other place in the language. Or am I not right?
P.S. The reason I’m asking is that I had a bug in the similar code in my project, where I used to iterate through a custom Collection from an external library, which was called like SomeTypeCollection, but in fact provided a collection of base type items and could have contained items of SomeOtherType. My fault, but still neither the language, nor the compiler provided any explicit hints/warnings, which is quite unusual for C#…
Think back to before generics…
foreachhad to cast so that you could do sensible things like:instead of:
The latter is just icky, IMO. Providing an implicit cast is unlike the rest of the language, but makes it much easier to use in the vast majority of cases.
I suspect that if C# had had generics and extension methods to start with (so we could use
OfTypeandCast) thatforeachwouldn’t be specified in quite the same way.Note that there’s even more oddness in
foreach: the type doesn’t have to implementIEnumerableat all. So long as it has aGetEnumeratormethod which returns something which in turn hasMoveNext()andCurrent, the C# compiler is happy. This meant you could implement a “strongly typed iterator” (to avoid boxing) before generics.