为什么我不能使用AddRange添加子类项?

时间:2009-07-02 04:57:05

标签: c# addrange liskov-substitution-principle

我有两个类...... Parcel和FundParcel ......我正在尝试将子类型的IEnumerable转换为超类型的IList ....

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

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

这些用于方法中的另一个类,如下所示:

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

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

    return parcels;
}

我不明白为什么foreach声明不能简化为:

parcels.AddRange(fundParcels);

我基本上得到一个错误,上面写着“参数类型'System.Colection.Generic.IEnumerable<FundParcel>' is not assignable to parameter type 'System.Collections.Generic.IEnumerable<Parcel>'"

但如果是这样,那么我不明白为什么parcels.Add有效...

我觉得整个方法应该可以替换为该行:

return (List<Parcel>)fundParcels;

...或者也许这个方法可以全部废弃,因为子类型应该可以替代它们的超类型。

在这种情况下,任何人都可以解释与AddRange的交易是什么以及为什么在这种情况下可能需要for循环?

2 个答案:

答案 0 :(得分:4)

This SO可能会回答您的问题,并会指出有关即将推出的C#4.0的参考文献,该版本将在一定程度上支持Co- / Contra-variance。

答案 1 :(得分:1)

考虑以下代码:

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

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

如果继承类的容器也从基类的容器继承,则上述代码有效,并生成一个继承类的列表包含基类对象的情况。

相关问题