What does the following code do?
class Base { }
class Derived : Base { }
class Test
{
void Foo(List<Base> list)
{
foreach (Derived obj in list)
{
// ...
}
}
}
I didn't expect it to even compile, but it does.
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 typeEand element typeT. Aforeachstatement of the formforeach (V v in x) embedded-statementis 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.
Absolutely nothing, but it does it in a very inefficient manner.
The order of operations is this:
Edit
Based on your edit, you run the risk of an InvalidCastException should any element of the list passed to Foo not actually be a Derived object.
Edit2
Why does it compile? Because foreach involves an implicit cast to Object for each item in the list, then another explicit cast to the specified type in the foreach block, in this case Derived
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With