5

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 (e.g. 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?

2
  • Is it really important to you to declare that the specific container types returns their specific policy types? You say that you want to reference the returned objects as PolicyDetailed, and that way you lose the specific information anyway! (Remember that AccidentContainer IS a DataContainer, and a AccidentContainer can thus be returned from a method with return type DataContainer without changing any signature at all) Commented Aug 5, 2012 at 22:02
  • I need it in other parts of the code, where I reference specific type of policy and use its secific container. I might consider using two methods - one would return a DataContainer object, second could return a specifc container (but it feels kind of clumsy :( ) Commented Aug 6, 2012 at 12:51

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.