tags:

views:

385

answers:

2

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?

+4  A: 

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.

Michael Bray
So then this is a known issue that will be solved in C#4.0?
mezoid
"Solved" is too strong a word - the general issue is still there, but C# 4 will fix it for *some* cases, including IEnumerable<T>.
Jon Skeet
+1  A: 

Consider this code:

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

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

If containers of inherited classes also inherited from containers of the base classes, the above code would be valid, and generate a case where a list of the inherited class contains an object of the base class.

Tal Pressman