这是我当前的类型层次结构:



我正在尝试在PlaneRegion中实现一个方法,该方法将在其派生类的列表上调用名为Shift()的方法,该列表在所有这些类中均称为PlaneBoundaries,但它们的类型不同

像这样:

public abstract class PlaneRegion<T>
{
    public abstract List<T> PlaneBoundaries { get; set; }
}


public class Polygon : PlaneRegion<LineSegment>
{
    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;

}


理想情况下,它还应该返回对象的副本作为其子类,而不修改原始对象。

目前,我有由两类实现的Interface IEdge:LineSegment和Arc。我将Generics用于抽象超类PlaneRegion,因为两个继承的类Polygons和NonPolygon都具有planeBoundaries,但是Polygon仅包含直线(lineSegments),而NonPolygon可以具有直线或曲线Lines(LineSegment或Arc),因此我实现了就像您在下面的摘录中所看到的那样,是这个问题:Override a Property with a Derived Type and Same Name C#

但是,由于PlaneRegion中的PlaneRegion和PlaneBoundaries是通用类型,因此当我尝试在PlaneBoundaries上调用shift时会引起问题。以下是当前如何实施Shift的示例:

//In PlaneRegion
public PlaneRegion<T> Shift(Shift inShift)
{
    //does not work because Shift isn't defined for type T
    this.PlaneBoundaries.Shift(passedShift);
}

//in Polygon
public override Polygon Shift(Shift passedShift)
{
    return new Polygon(this.PlaneBoundaries.Shift(passedShift));
}

//In NonPolygon
public override NonPolygon Shift(Shift passedShift)
{
    return new NonPolygon(this.PlaneBoundaries.Shift(passedShift));
}


有没有办法像这样在泛型列表上调用shift或将T的可能性限制为在编译时实现IEdge的类?我也尝试过将PlaneRegion中的Shift也设为通用,但是它也不起作用。

另外,理想情况下,我希望它返回原始对象的副本作为子对象,并修改那些对象的PlaneBoundaries而不是原始Objects PlaneBoundaries,但不要这样做。

最佳答案

您可以缩小您的PlaneRegion类,以仅接受T中IEdge接口的实现:

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


另外,在Shift函数中,您可能希望将其应用于列表中的每个项目,而不是整个列表,因此应将其更改为:

//In PlaneRegion
public PlaneRegion<T> Shift(Shift inShift)
{
    this.PlaneBoundaries.ForEach(x => x.Shift(passedShift));
}

10-04 11:32