2009-10-10 19 views
10

In questo momento ho un relativamente semplice configurazione di classe:C# comportamento foreach con classi derivate?

class A{ 
//stuff 
} 
class B:A{ 
//more stuff 
} 
public List<A> ListOfObjects; 

cosa sarebbe successo se lo faccio

foreach(B i in ListOfObjects) 

dovrei ottenere solo oggetti di tipo B? Applicerebbe qualche magia OO e convertirà tutto in Bs? Funzionerebbe anche questo?

risposta

22

Se l'elenco contiene A (o altre cose che non sono B o sottoclassi di B), si interromperà semplicemente con un cast non valido. Probabilmente vuoi:

foreach(B i in ListOfObjects.OfType<B>()) {...} 

in .NET 3.5. (Suppongo che la lista stessa non sia nullo, btw)

3

foreach liste tutti gli oggetti nella raccolta. Se il tipo di runtime di un elemento non è compatibile con il tipo della variabile iteratore (nel tuo caso i di tipo B) viene generata una TypeCasException.

Invece si può fare questo:

foreach(A i in ListOfObjects) 
{ 
    B b = i as B 
    if (b!=null) .. 
} 

Oppure è possibile filtrare l'elenco prima iterazione di esso. La soluzione più semplice sarà una query linq.

7

Io personalmente uso var come variabile di ciclo in foreach in tutte le circostanze, per evitare qualsiasi possibilità di un cast runtime non valido. In questo modo, il tipo di variabile del ciclo sarà il tipo statico degli elementi della raccolta; se vuoi qualcos'altro, usa OfType per eseguire un cast sicuro per il filtraggio.

Some more explanation here.

Problemi correlati