如何将子类作为参数传递以覆盖抽象方法?

3
考虑以下抽象类:
我希望能够使用派生自LineContainer的类来重写抽象的CanBeGroupedWith方法,并使一切正常。这是否可行?
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 
    }

}

需要帮助或协助/建议将不胜感激


有一些你想要的东西是有道理的。抽象类是你的派生类必须实现的契约,如果我们在这种情况下使用抽象类类型来引用你的派生类实例,那将会有问题。正如你提到的,你可以使用泛型,因为在这种情况下你必须具体指定。 - Khanh TO
3个回答

1

不。你的评论是错误的。

因为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());
    }
}

1
你可以使用泛型来指定类型必须与派生类型匹配,就像这样。
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>继承的类型的方式。

非常感谢您的帮助。但是,如果我在更高级别的模块中要调用LineContainer抽象类,我应该如何做呢?如果我必须这样做,那么我将被迫使用泛型来指定它 - 有没有什么简化的方法? - BenKoshy
@BKSpurgeon 如果你的意思是想要一个指向派生类型的 LineContainer 引用,那么是的,它必须将派生类型作为泛型类型进行指定。如果你希望代码能够处理不同的派生类型,那么该代码也必须是泛型的。最终,在某个时刻你必须指定正在使用的派生类型。 - juharr

0
你也可以将这个方法定义为泛型,像这样:
public abstract bool CanBeGroupedWith<T>(T container) where T : LineContainer;

然后在DimensionContainer类中像这样覆盖它。
public override bool CanBeGroupedWith<DimensionContainer>(DimensionContainer container)
{
}

如果抽象类中的方法是通用的,那么派生类中也必须是通用的。具体而言,你不能像那样放置一个具体类型。这就是你放置通用类型名称的地方。只有在调用通用方法时才能指定具体类型。 - juharr
你在开玩笑吗? - Jiji

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接