2011-11-10 11 views
8

Eventuali duplicati:
Foreach can throw an InvalidCastException?Perché il compilatore ha lasciato questo slittamento?

Si consideri il seguente blocco di codice

public class Base 
{ 
} 

public class DerivedLeft : Base 
{ 
} 

public class DerivedRight : Base 
{ 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Base> list = new List<Base> { new DerivedLeft(), new DerivedRight() }; 
     foreach (DerivedLeft dl in list) 
     { 
      Console.WriteLine(dl.ToString()); 
     } 
    } 
} 

Avviso il cast dalla base alla DerivedLeft nella dichiarazione foreach. Compilano bene (Visual Studio 2010), senza errori o avvisi. Ovviamente, nella seconda iterazione del ciclo otterremo una InvalidCastException. Se mi venisse posta una domanda sulla reazione del compilatore a tale codice, direi senza dubbio che il compilatore non lascerà passare inosservato questo e produrrà almeno un avvertimento. Ma a quanto pare non è così. Quindi, perché il compilatore ha permesso a questo scivolone?

risposta

2

Perché la lista è di tipo List<Base> e la variabile dl nel ciclo foreach è di tipo DerivedLeft che ha Base come classe base. Quindi può può funzionare durante il runtime, ma non ha a. Il compilatore non sta verificando l'inizializzazione della tua lista.

+0

Credo che il compilatore non controlla l'inizializzazione .... es. se inserisco MyOtherClass, esiste un'eccezione di compilazione –

+0

@RoyiNamir: Sì, il compilatore verifica se l'inizializzazione è corretta, ma non controlla se sono presenti solo gli elementi corrispondenti quando raggiunge il ciclo foreach. – Fischermaen

+0

corretto ............ –

0

Prevedendo al compilatore di generare un errore su questo è come mi aspettavo di generare un errore su questo:

Base b = new DerivedRight(); 
DerivedLeft d = (DerivedLeft)b; 
+0

infatti il ​​compilatore genererà un errore su questo, dal momento che non hai fornito il nome della variabile per DerivedLeft :) – Trogvar

+0

true ......... :) – nogola

+0

In tutta onestà, il cast implicito coinvolto in 'foreach' non è così ovvio, a meno che uno non abbia codificato con 'C#' per .NET1.0 o 1.1, in cui la mancanza di generici significava che sarebbe stato molto più imbarazzante non avere il cast implicito, come ogni 'foreach' che non ha avere a che fare con 'object' ne avrebbe avuto bisogno. –

Problemi correlati