The behavior you are observing is according to section 8.8.4 The foreach statement of the C# language specification. This section defines the semantics of the foreach
statement as follows:
[...] The above steps, if successful, unambiguously produce a collection type C
, enumerator type E
and element type T
. A foreach
statement of the form
foreach (V v in x) embedded-statement
is then expanded to:
{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
// here the current item will be casted
v = (V)(T)e.Current;
embedded-statement
}
}
finally {
// Dispose e
}
}
The reason that the compiler inserts this explicit cast is historic. C# 1.0 didn't have generics so in order to allow simple code like this
ArrayList list = new ArrayList();
list.Add(1);
foreach (int i in list)
{
...
}
it was decided to let the compiler introduce the cast.