问题
Here is my current Type Hierarchy:

I am trying to implement a method in PlaneRegion
that will call a method named Shift()
on a list in its derived classes where the list is called PlaneBoundaries in all of them but they are of different types
like so:
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;
}
Ideally it should also return a copy of the object as its subclass and not modify the original object.
Currently, I have the Interface IEdge implemented by two classes: LineSegment and Arc. I am using Generics for the abstract superclass PlaneRegion because the two inheriting classes, Polygons and NonPolygon, both have planeBoundaries, but a Polygon only contains straight lines (lineSegments) while the NonPolygon can have straight or curved Lines(LineSegment or Arc) so I implemented like in this question as you can see in the snippets below: Override a Property with a Derived Type and Same Name C#
However, because PlaneRegion and PlaneBoundaries in PlaneRegion are a generic type it causes problems when I try to call shift on the PlaneBoundaries. Below are examples of how Shift is currently implemented:
//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));
}
Is there a way to call shift on a Generic List like this or to limit the possibilities of T to classes that implement IEdge at compile time? I have tried making Shift in PlaneRegion a generic as well but it did not work either.
Also, Ideally I want it to return copies of the original objects as the child object and to modify the PlaneBoundaries on those instead of the original Objects PlaneBoundaries but do not how to do that.
回答1:
You can narrow your PlaneRegion
class to admit only implementations of IEdge
interface in T:
public abstract class PlaneRegion<T> where T : IEdge
{
public abstract List<T> PlaneBoundaries { get; set; }
}
Also, in the Shift
function, you may want to apply it to every item in the list, not the whole list, so you should change it to:
//In PlaneRegion
public PlaneRegion<T> Shift(Shift inShift)
{
this.PlaneBoundaries.ForEach(x => x.Shift(passedShift));
}
来源:https://stackoverflow.com/questions/26128002/calling-a-method-on-a-list-of-generic-type-from-abstract-parent-class