简体   繁体   中英

C# - advanced inheritance

Please take a look at my class structure. I think I would like to have more fun with inheritance than it is possible.

First there is a base abstract class:

public abstract class PolicyDetailed
{
    internal abstract DataContainer GetActiveAsset();
}

Next there is another abstract class, which is generic:

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

Lastly there is a specific policy class. AccidentContainer inherits from DataContainer:

public class PolicyAccident : PolicyDetailed<AccidentContainer>
{
    internal override AccidentContainer GetActiveAsset()
    {
        return null;
    }
}

During compilation I get the following error:

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

I am not sure what modifiers I should use here to get it to work. Maybe I should also write what I would like to achieve: I have a collection of policy objects of different type (eg PolicyAccident, PolicyTravel etc.) which inherit from PolicyDetailed with different types of DataContainer (AccidentContainer, TravelContainer etc.). I would like to call "GetActiveAsset" method on each of them without knowing their specific type and referencing them through PolicyDetailed. At the same time I would like each class to return their specific Datacontainer subclass. Is that possible?

The problem is that you can't override the non-generic method in the same class as you declare any other method with the same signature.

There are a few options:

  • 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM