2009-07-02 7 views
0

Ich habe zwei Klassen .... Parcel und FundParcel ... und ich versuche, eine IEnumerable des Subtyps in eine IList der Supertyp ....Warum kann ich AddRange nicht zum Hinzufügen von Unterklasse-Elementen verwenden?

public class FundParcel : Parcel 
{ 
    /* properties defined here */ 
} 

public class Parcel 
{ 
    /* properties defined here */ 
} 

Diese in einem anderen verwendet werden zu konvertieren Klasse in einem Verfahren, wie folgt:

private IList<Parcel> ExtractParcels(IEnumerable<FundParcel> fundParcels) 
{ 
    var parcels = new List<Parcel>(); 

    foreach (var fp in fundParcels) 
     parcels.Add(fp); 

    return parcels; 
} 

Was ich nicht verstehe, warum die foreach ist Aussage nicht zu reduzieren:

parcels.AddRange(fundParcels); 

ich im Grunde einen Fehler, der „Arg sagt UMENT Typ 'System.Colection.Generic.IEnumerable<FundParcel>' is not assignable to parameter type 'System.Collections.Generic.IEnumerable<Parcel>'"

Aber wenn das der Fall ist, dann verstehe ich nicht, warum parcels.Add funktioniert ...

Ich fühle mich, als ob das gesamte Verfahren sollte mit der Linie austauschbar sein:

return (List<Parcel>)fundParcels; 

... oder vielleicht kann das Verfahren alltogether verschrottet werden, da Subtypen für ihren Supertyp ersetzbar sein sollte ..

jemand erklären kann, was das Geschäft mit AddRange in diesem Fall ist und warum die for-Schleife in diesem Fall notwendig sein kann, ?

+0

Mögliches Duplikat von [Warum unterstützt C#/CLR nicht die Methode zum Überschreiben der Co/Kontra-Varianz?] (Http://StackOverflow.com/Questions/837134/Why-does-cclr-not-support-method- Override-Co-Contra-Varianz) – TheLethalCoder

Antwort

4

This SO wird wahrscheinlich Ihre Frage beantworten und werden Sie auch über bevorstehende C# 4.0 auf Referenzen verweisen, die Co-/Contra-Varianz zu einem gewissen Grad unterstützen.

+0

Also ist dies ein bekanntes Problem, das in C# 4.0 gelöst wird? – mezoid

+1

"Gelöst" ist zu stark ein Wort - das allgemeine Problem ist immer noch da, aber C# 4 wird es für * einige * Fälle beheben, einschließlich IEnumerable . –

1

Betrachten Sie diesen Code:

void AddParcelToParcelList(List<Parcel> parcels) { 
    parcels.add(new Parcel()); 
} 

List<FundParcel> fundParcels = new List<FundParcels>(); 
AddParcelToParcelList(fundParcels); 

Wenn Container von geerbten Klassen auch aus Containern der Basisklassen geerbt, würde der obige Code gültig sein, und einen Fall erzeugen, in dem eine Liste der vererbten Klasse enthält ein Objekt der Basisklasse.