C# - 高级继承

5
请看一下我的类结构。我认为我希望在继承方面有更多的乐趣,而这是可能的。
首先有一个基础抽象类:
public abstract class PolicyDetailed
{
    internal abstract DataContainer GetActiveAsset();
}

接下来有另一个抽象类,它是通用的:

public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer
{
    internal new abstract T GetActiveAsset();
}

最后还有一个特定的策略类。AccidentContainer继承自DataContainer:
public class PolicyAccident : PolicyDetailed<AccidentContainer>
{
    internal override AccidentContainer GetActiveAsset()
    {
        return null;
    }
}

编译时我遇到了以下错误:

'PolicyAccident' does not implement inherited abstract member 'PolicyDetailed.GetActiveAsset()'  

我不确定我应该在这里使用哪些修饰符才能使它工作。也许我还应该写出我想要实现的内容:我有一组不同类型的策略对象(例如PolicyAccident,PolicyTravel等),它们从具有不同类型DataContainer的PolicyDetailed继承而来(AccidentContainer,TravelContainer等)。我想在不知道它们特定类型并通过PolicyDetailed引用它们的情况下调用每个对象的“GetActiveAsset”方法。同时,我希望每个类都返回其特定的Datacontainer子类。这可能吗?


你真的认为声明特定容器类型返回其特定策略类型很重要吗?你说你想将返回的对象引用为PolicyDetailed,但这样你还是失去了具体信息!(请记住,AccidentContainer是DataContainer,因此可以从返回类型为DataContainer的方法中返回AccidentContainer而不需要更改任何签名) - olagjo
我需要在代码的其他部分中使用它,其中我引用特定类型的策略并使用其特定容器。我可能考虑使用两种方法 - 一种将返回DataContainer对象,第二种将返回特定容器(但感觉有点笨拙:() - Rummy
1个回答

6

问题在于你不能在同一类中用相同的签名声明任何其他方法并覆盖非泛型方法。

有几个选择:

  • By far the simplest is to give the two methods different names. Then you can give an implementation in PolicyDetailed<T> which just delegates to the new abstract method:

    public abstract class PolicyDetailed
    {
        internal abstract DataContainer GetActiveAsset();
    }
    
    public abstract class PolicyDetailed<T> : PolicyDetailed where T : DataContainer
    {
        internal abstract T GetActiveAssetGeneric();
    
        internal override DataContainer GetActiveAsset()
        {
            return GetActiveAssetGeneric();
        }
    }
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer>
    {
        internal override AccidentContainer GetActiveAssetGeneric()
        {
            return null;
        }    
    }
    
  • You could introduce another level of inheritance, introducing a new method name just for bridging purposes. This is pretty ugly:

    public class DataContainer {}
    public class AccidentContainer : DataContainer{}
    
    public abstract class PolicyDetailed
    {
        internal abstract DataContainer GetActiveAsset();
    }
    
    // This only exists to satisfy the base class abstract member,
    // but at the same time allowing PolicyDetailed<T> to introduce
    // a new member with the same name.
    public abstract class PolicyDetailedBridge<T> : PolicyDetailed
        where T : DataContainer
    {
        protected abstract T GetActiveAssetGeneric();
    
        internal override DataContainer GetActiveAsset()
        {
            return GetActiveAssetGeneric();
        }
    }
    
    public abstract class PolicyDetailed<T> : PolicyDetailedBridge<T>
        where T : DataContainer
    {
        protected sealed override T GetActiveAssetGeneric()
        {
            // Call the *new* abstract method. Eek!
            return GetActiveAsset();
        }
    
        internal abstract new T GetActiveAsset();
    }
    
    public class PolicyAccident : PolicyDetailed<AccidentContainer>
    {
        internal override AccidentContainer GetActiveAsset()
        {
            return null;
        }            
    }
    
  • You could make the non-generic PolicyDetailed class an interface instead, and use explicit interface implementation to declare a new abstract method and still implement the interface.


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