Search code examples
c#addrangeliskov-substitution-principle

Why can't I use AddRange to add subclassed items?


I have two classes.... Parcel and FundParcel...and I'm trying to convert an IEnumerable of the subtype to an IList of the supertype....

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

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

These are used in another class in a method as follows:

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

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

    return parcels;
}

What I don't understand is why the foreach statement can't be reduced to:

parcels.AddRange(fundParcels);

I basically get an error that says "Argument type 'System.Colection.Generic.IEnumerable<FundParcel>' is not assignable to parameter type 'System.Collections.Generic.IEnumerable<Parcel>'"

But if that's the case then I don't understand why parcels.Add works...

I feel as though the entire method ought to be replaceable with the line:

return (List<Parcel>)fundParcels;

...or maybe the method can be scrapped alltogether since subtypes should be substitutable for their supertype..

Can anyone explain what the deal is with AddRange in this case and why the for loop may be necessary in this case?


Solution

  • This SO will probably answer your question and also will point you to references about upcoming C# 4.0 which will support Co-/Contra-variance to a certain degree.