Search code examples
c#inheritanceoverridingabstract-class

Is it possible to override the nested class definition of an abstract parent, within an inheriting class?


Context

I have an scenario in which I wish to define several Bar classes, each of which must define Request, Response and Error classes of their own. For this reason, I have written an abstract Foo class, within an intension to force an the implementation.

Request, Response and Error share a base class, PDU, and must implement their respective interfaces. Each Bar requires a sufficiently unique Request, Response and Error, that they must be independently defined.

Furthermore, the Request, Response and Error of each Bar shall not be instantiated outside of that Bar, so it seems correct (at least to me) that the class definitions should be nested.

Question

Is it possible to override a nested class definition within a child, inheriting from an abstract parent? Or at least to achieve the same through another approach?

Illegal Example

Below is an illegal code example of how I would of liked to write it:

public abstract class Foo
{
    public class Request: PDU, IRequest
    { }

    public class Response : PDU, IResponse
    { }

    public class Error : PDU, IException
    { }
}

public class Bar : Foo
{
    public override Request
    {
        // Definition of Request goes here
    }

    public override Response
    {
        // Definition of Response goes here
    }

    public override Error
    {
        // Definition of Error goes here
    }
}

Solution

  • It isn't possible to override a nested class, so your current approach won't work. However, I think this is what you are trying to achieve.

    My advice would be to use interfaces and generics. So let's say you have your 3 interfaces:

    public interface IRequest
    {
        //snip
    }
    public interface IResponse
    {
        //snip
    }
    
    public interface IException
    {
        //snip
    }
    

    Now you can make your base class look like this:

    public abstract class BaseThing<TRequest, TResponse, TError>
        where TRequest : IRequest
        where TResponse : IResponse
        where TError : IException
    {
        // An example method
        public abstract TResponse GetThing(TRequest request);
    }
    

    Now you can make some concrete definitions of the above things:

    public class FooRequest : IRequest
    {
        //snip
    }
    
    public class FooResponse : IResponse
    {
        //snip
    }
    
    public class FooError : IException
    {
        //snip
    }
    
    public class FooThing : BaseThing<FooRequest, FooResponse, FooError>
    {
        public override FooResponse GetThing(FooRequest request)
        {
            //snip
        }
    }