List of a Generic Typed Parent not Accepting a Child with a Type that is a Subtype of the Parent List's Type

417 views Asked by At

Here is my current class diagram:

enter image description here

As you can see, both Polygon and NonPolygon are types of PlaneRegion and LineSegment implements IEdge.The PlaneRegion is Generic so we can make its list of PlaneBoundaries either IEdge for NonPolygon so it can have LineSegment or arc, or so that they can be only LineSegment for Polygon. Below is samples of the classes to show how it is implemented:

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;
}

This all works fine, but when I try to make a list of PlaneRegion<IEdge> it will not let me add a Polygon object to the list despite Polygon being a PlaneRegion<LineSegment> and LineSegment implemting IEdge. This is an example of the code that gives me a compile time error:

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);

Is there a way to add polygon1 to this list that is type safe? I tried casting polygon1 to type PlaneRegion<IEdge> but that gave a compile error that it cannot convert the types. I know I can do (PlaneRegion<IEdge>)(object) but it seems sloppy and unsafe so it seems there should be a better way.

1

There are 1 answers

0
Jose M. On

Try this, it works fine for me:

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