【问题标题】:List of a Generic Typed Parent not Accepting a Child with a Type that is a Subtype of the Parent List's Type不接受类型是父列表类型的子类型的子类型的通用类型父列表
【发布时间】:2014-11-27 13:26:55
【问题描述】:

这是我当前的类图:

如您所见,PolygonNonPolygon 都是 PlaneRegionLineSegment 实现 IEdge 的类型。PlaneRegion 是通用的,因此我们可以将其列表 PlaneBoundaries 或 @987654330 @ 代表NonPolygon,所以它可以有LineSegmentarc,或者它们只能是LineSegment 代表Polygon。下面是类的示例,展示了它是如何实现的:

public class PlaneRegion<T> : Plane, where T : IEdge
{
    public virtual List<T> PlaneBoundaries { get; set; }
}

public class Polygon : PlaneRegion<LineSegment>
{
    #region Fields and Properties
    public override List<LineSegment> PlaneBoundaries
    {
        get { return _planeBoundaries; }
        set { _planeBoundaries = value; }
    }
    protected List<LineSegment> _planeBoundaries;
}

public class NonPolygon : PlaneRegion<IEdge>
{
    public override List<IEdge> PlaneBoundaries
    {
        get { return _planeBoundaries; }
        set { _planeBoundaries = value; }
    }
    private List<IEdge> _planeBoundaries;
}

这一切都很好,但是当我尝试创建PlaneRegion&lt;IEdge&gt; 的列表时,尽管PolygonPlaneRegion&lt;LineSegment&gt;LineSegment 实现@987654342,但它不会让我将Polygon 对象添加到列表中@。这是给我一个编译时错误的代码示例:

List<PlaneRegion<IEdge>> planes = new List<PlaneRegion<IEdge>>();

Polygon polygon1 = new Polygon();      
NonPolygon nonPolygon1 = new NonPolygon();

planes.Add(polygon1); //says that .Add() has some invalid arguments
planes.Add(nonPolygon1);

有没有办法将polygon1 添加到这个类型安全的列表中?我尝试将polygon1 转换为PlaneRegion&lt;IEdge&gt; 类型,但这给出了无法转换类型的编译错误。我知道我可以做到(PlaneRegion&lt;IEdge&gt;)(object),但它看起来草率且不安全,所以似乎应该有更好的方法。

【问题讨论】:

  • 给定类型UV以及泛型类型G&lt;T&gt;U:V并不暗示G&lt;U&gt;:G&lt;V&gt;——也就是说,类型之间的继承关系并不意味着泛型派生之间的继承关系从那些类型。所以PlaneRegion&lt;LineSegment&gt;不是PlaneRegion&lt;IEdge&gt;
  • 强制转换没有帮助,顺便说一句 - 这将在执行时失败。简单地说,PlaneRegion&lt;LineSegment&gt;不是PlaneRegion&lt;IEdge&gt;。考虑一下region.PlaneBoundaries.Add(new Arc()) 的作用,如果region 被标记为PlaneRegion&lt;IEdge&gt; 但在执行时是PlaneRegion&lt;LineSegment&gt;...
  • 我知道问题出在哪里,但有没有办法做这样的事情,或者用另一种方法来实现避免问题的类似结果?
  • 您是否尝试过创建IPlaneRegion&lt;T&gt; 接口并使其成为协变的?然后您可以将其用作编译时类型。我可能错了,但据我所知,您当前的课程满足条件。

标签: c# generics inheritance interface geometry-class-library


【解决方案1】:

试试这个,对我来说很好用:

public class Polygon : PlaneRegion<IEdge> 
{
    public new List<LineSegment> PlaneBoundaries
    {
        get { return (_planeBoundaries); }
        set { _planeBoundaries = value; }
    }
    protected List<LineSegment> _planeBoundaries;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-19
    • 2021-06-12
    • 2015-12-12
    • 2023-03-06
    • 2021-05-16
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    相关资源
    最近更新 更多