BenKoshy
BenKoshy

Reputation: 35585

How to pass sub-class as a parameter to override an abstract method?

Consider the following abstract class:

I would like to be able to override the abstract CanBeGroupedWith method with a derived class of LineContainer and to have everything work. Is this possible?

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 
    }

}

Any help or assitance/advice much appreciated

Upvotes: 3

Views: 258

Answers (2)

juharr
juharr

Reputation: 32266

You can use generics to specify that the type has to match the derived type like this.

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)
    {
    }
}

Also note that this does not limit the generic type to the derived class it's applied too. It's just how you can control the type and at least constrain it to a type that does inherit from LineContainer<T>.

Upvotes: 1

Adam G
Adam G

Reputation: 1323

No. Your comment

since the DimensionContainer is in fact a LineContainer

is wrong. It might be, or might not be. All you are promised is a LineContainer.

See the contrived class below. Can you really assume that it is a DimensionContainer?

public class NotADimensionContainer : LineContainer
{
  // etc        
}

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

Upvotes: 1

Related Questions