Ковариация с возвращаемыми функциями типами

У меня примерно следующая иерархия типов (я знаю, что все ребра на NonPolygon не будут дугами.

введите здесь описание изображения

Я пытаюсь выполнить Extrusions на всех PlaneRegions, в результате чего возвращаются объекты Solid. Когда я экструдирую многоугольник, я хочу вернуть многогранник. Когда я возвращаю NonPolygon, я хочу вернуть NonPolyhedron, который также является телом.

public class PlaneRegion
{
    public IEnumerable<IEdge> Edges;

    public virtual Solid Extrude()
    {
        throw new NotImplementedException();
    }  
}

Я расширяю приведенный выше класс двумя производными классами, которые используют разные производные типы IEdge в качестве краев. И я также хотел бы, чтобы их методы выдавливания возвращали различные производные объекты Solid.

public class Polygon: PlaneRegion
{

    public Polygon(List<LineSegment> passedSegments)
    {
        this.Edges = passedSegment;
    }

    public new Polyhedron Extrude()
    {
        List<LineSegment> segments = Edges as List<LineSegment>;

        foreach (var segment in segments)
        {
           //do stuff
        }

        return new Polyhedron(new List<Polygon>(){ this});
    }
}

public class NonPolygon: PlaneRegion
{

    public NonPolygon(List<Arc> passedArcs)
    {
        this.Edges = passedArcs;
    }

    public new NonPolyhedron Extrude()
    {
        foreach (var arc in Edges as List<Arc>)
        {
            //do stuff
        }

        return new NonPolyhedron(new List<NonPolygon>(){this});
    }
}

Когда я пытаюсь выполнить следующий код, я вызываю реализацию PlaneRegion Extrude() вместо реализаций производных классов. Я не могу переопределить метод Extrude в PlaneRegion, потому что у меня возвращаются «другие» типы. Как правильно вернуть производный тип из функции в производном типе? (Если есть способ?)


person jth41    schedule 20.10.2014    source источник


Ответы (1)


В качестве возвращаемого значения используйте общий базовый тип Solid, а не Polyhedron. В конце концов, базовый метод Extrude не знает и не заботится о том, является ли возвращаемое значение Polyhedron или NonPolyhedron. Обратите внимание, что вы по-прежнему возвращаете объект Polyhedron, просто вызывающая сторона получает объект как Solid. Вызывающий может вернуть его обратно в Polyhedron, если по какой-то причине это его волнует (но обычно, если вы правильно используете полиморфизм, этого не произойдет).

Примечание: на вашей диаграмме у вас есть «Solid», наследующий «Solid». Я предполагаю, что подкласс "Solid" должен был быть "NonPolyhedron".

person Peter Duniho    schedule 20.10.2014