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 typeE
and element typeT
. Aforeach
statement of the formforeach (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.
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