【问题标题】:Why can't I use AddRange to add subclassed items?为什么我不能使用 AddRange 添加子类项?
【发布时间】:2009-07-02 04:57:05
【问题描述】:

我有两个类.... 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&lt;FundParcel&gt;' is not assignable to parameter type 'System.Collections.Generic.IEnumerable&lt;Parcel&gt;'"

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

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

return (List<Parcel>)fundParcels;

...或者该方法可以一起废弃,因为子类型应该可以替代它们的超类型..

谁能解释在这种情况下与 AddRange 的关系以及为什么在这种情况下可能需要 for 循环?

【问题讨论】:

标签: c# addrange liskov-substitution-principle


【解决方案1】:

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

【讨论】:

  • “已解决”这个词太强了 - 一般问题仍然存在,但 C# 4 将针对 一些 情况修复它,包括 IEnumerable
【解决方案2】:

考虑这段代码:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-28
    • 2011-04-07
    相关资源
    最近更新 更多