What does the following code do?
class Base { } class Derived : Base { } class Test { void Foo(List<Base> list) { foreach (Derived obj in list) { // ... } } }
I did not expect it to even compile, but it is.
The behavior you observe corresponds to section 8.8.4. Presentation of the foreach C # language specification. This section defines operator semantics foreachas follows:
foreach
[...] The above steps, if successful, uniquely create a collection Ctype, an enumerator type, Eand an element type T. A foreachform expressionforeach (V v in x) embedded-statement then expand 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 above steps, if successful, uniquely create a collection Ctype, an enumerator type, Eand an element type T. A foreachform expression
C
E
T
foreach (V v in x) embedded-statement
then expand 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 } }
, , . # 1.0 , ,
ArrayList list = new ArrayList(); list.Add(1); foreach (int i in list) { ... }
, .
:
EditInvalidCastException, - , Foo, Derived.
InvalidCastException
Foo
Derived
Edit2? foreach Object , foreach, Derived
Object
foreach . , . Base Derived, , .
Base
, , . , :
{ List<Base> list = new List<Base>(); // creates new, empty list of Base foreach (Derived obj in list) { // ... } }
, ?
EDIT .
InvalidCastException, , Derived. Derived ' "", .
Enumerator<Base> enumerator = new List<Base>().GetEnumerator(); while (enumerator.MoveNext()) { Derived obj = (Derived) enumerator.Current; // ... }
, InvalidCastException, - Derived.
, : . , .
Derived , Derived, , Base. , Derived .
, , List<Derived>.
List<Derived>
,
list.Cast<Derived>();
. u