Perché non posso usare AddRange per aggiungere elementi sottoclassi?
-
21-08-2019 - |
Domanda
Ho due classi .... pacco e FundParcel ... e sto cercando di convertire un IEnumerable del sottotipo a un IList del supertipo ....
public class FundParcel : Parcel
{
/* properties defined here */
}
public class Parcel
{
/* properties defined here */
}
Questi sono utilizzati in un'altra classe in un metodo come segue:
private IList<Parcel> ExtractParcels(IEnumerable<FundParcel> fundParcels)
{
var parcels = new List<Parcel>();
foreach (var fp in fundParcels)
parcels.Add(fp);
return parcels;
}
Quello che non capisco è il motivo per cui l'istruzione foreach non può essere ridotta a:
parcels.AddRange(fundParcels);
Io fondamentalmente ottengo un errore che dice "Tipo di argomento 'System.Colection.Generic.IEnumerable<FundParcel>' is not assignable to parameter type 'System.Collections.Generic.IEnumerable<Parcel>'"
Ma se questo è il caso, allora non capisco il motivo per cui parcels.Add funziona ...
Mi sento come se l'intero metodo dovrebbe essere sostituibile con la linea:
return (List<Parcel>)fundParcels;
... o forse il metodo può essere scartata in quanto alltogether sottotipi dovrebbero essere sostituibili per la loro supertipo ..
Qualcuno può spiegare che cosa l'affare è con AddRange in questo caso e il motivo per cui il ciclo for può essere necessario in questo caso?
Soluzione
Questa volontà SO probabilmente rispondere alla tua domanda e anche punterà di riferimenti sui prossimi C # 4.0 che sosterranno Co / Contra-varianza a un certo punto.
Altri suggerimenti
Si consideri questo codice:
void AddParcelToParcelList(List<Parcel> parcels) {
parcels.add(new Parcel());
}
List<FundParcel> fundParcels = new List<FundParcels>();
AddParcelToParcelList(fundParcels);
Se i contenitori di classi ereditate anche ereditate dai contenitori delle classi di base, il codice precedente sarebbe valida, e generare un caso in cui l'elenco di classe ereditata contiene un oggetto della classe base.