Как передать подкласс в качестве параметра для переопределения абстрактного метода? - PullRequest
0 голосов
/ 30 апреля 2018

Рассмотрим следующий абстрактный класс:

Я хотел бы иметь возможность переопределить абстрактный метод CanBeGroupedWith производным классом LineContainer и заставить все работать. Возможно ли это?

public abstract class LineContainer
{
    public abstract IEnumerable<Line3d> Get3dLines();

    public abstract bool CanBeGroupedWith(LineContainer container);
}

public class DimensionContainer : LineContainer
{        

    public override IEnumerable<Line3d> Get3dLines()
    { //....etc        
    }

    public override bool CanBeGroupedWith(DimensionContainer container)
    {
            /// I want this to be able to work with a DimensionContainer
            /// parameter since the DimensionContainer is in fact 
            /// a LineContainer.
            /// I want to be able to use the DimensionContainer as a
            /// parameter because I want to make use of some specific
            /// fields within it.

            /// I originally tried to have the LineContainer class as a generic class
            /// but I didn't know how to call it while still retaining the CanBeGroupedWith method.
            /// I would then have to specify the type the type in a higher
            /// level class i.e. LineContainer<DimensionContainer> which is
            /// defeats the purpose of the higher level function?                
            /// Any assistance much appreciated 
    }

}

Любая помощь или помощь / совет высоко ценится

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

Вы можете использовать обобщения, чтобы указать, что тип должен соответствовать производному типу, как этот.

public abstract class LineContainer<T> where T : LineContainer<T>
{
    public abstract IEnumerable<Line3d> Get3dLines();

    public abstract bool CanBeGroupedWith(T container);
}

public class DimensionContainer : LineContainer<DimensionContainer>
{     
    public override IEnumerable<Line3d> Get3dLines()
    {       
    }

    public override bool CanBeGroupedWith(DimensionContainer container)
    {
    }
}

Также обратите внимание, что это не ограничивает универсальный тип производным классом, к которому он также применяется. Это просто, как вы можете контролировать тип и, по крайней мере, ограничить его типом, который наследуется от LineContainer<T>.

0 голосов
/ 30 апреля 2018

Вы также можете просто сделать метод универсальным, например:

public abstract bool CanBeGroupedWith<T>(T container) where T : LineContainer;

Затем переопределите это так в классе DimensionContainer.

public override bool CanBeGroupedWith<DimensionContainer>(DimensionContainer container)
{
}
0 голосов
/ 30 апреля 2018

Нет. Ваш комментарий

, поскольку DimensionContainer фактически является LineContainer

неправильно. Это может быть или не быть. Все, что вам обещано - это LineContainer.

См. Надуманный класс ниже. Вы действительно можете предположить, что это DimensionContainer?

public class NotADimensionContainer : LineContainer
{
  // etc        
}

internal class Program
{
    private static void Main()
    {
        var dimensionContainer = new DimensionContainer();
        var canGroup = dimensionContainer.CanBeGroupedWith(new NotADimensionContainer());
    }
}
...