开发者

Overriding a nested class functions or use delegates?**

I have a base class which has a nested type, inside. There's a function in the oute开发者_开发百科r (base) type which would be overridden by it's children later. In fact this function belongs to the inner type from the OO prespective but still I need it, to be overridden by subtypes of the base class.

Should I use this function as a callback from the inner type or just move it inside the inner type and let's the subtypes to override it from there?

EDIT: Sample code added

class A
{
    protected void func() { /* do something */ }
    class B { /**/ }
}

// OR

class A
{
    class B
    {
        protected void func() { /* do something */ }
    }
}

// Then

class C : A
{
    override func() { /**/ }
}


My suggestion is to crate a delegate for the inner type function which is initiated by the constructor of the base class:

internal class BaseClass
{
    public BaseClass(Action myAction)
    {
        this.innerType = new InnerType(myAction);
    }

    public BaseClass()
    {
        // When no function delegate is supplied, InnerType should default to
        // using its own implementation of the specific function
        this.innerType = new InnerType();
    }
}

As you see, deriving types can call the base constructor with :base (overridenAction) where they can provide their own implementation of the function right to the innermost type. Of course, you are not obligated to use Action but any delegate you want.


IMO what you are describing looks like The Strategy design pattern. Consider using this pattern. Your code would be much more maintainable as it contains well recognizable pattern. You also can take a look at state design pattern, usually you have to choose between these two, they are closely connected.


In this scenario:

class A
{
    class B
    {
        protected void func() { // do something }
    }
}

You cannot derive from class A and override func() in class B.

From your description it seems that A-derived classes should be able to override some function (or functionality) in the inner class B which indicates that you maybe should rethink your design. Either extract B and don't make it an inner class or make the functionality you want to override an explicit dependency via an interface like this:

class A
{
    private B _MyB;
    public A(ISomeBehaviour behaviour)
    {
        _MyB = new B(behaviour);
    }
}

In anyway if you want to stick with your design then I would not recommend the delegate approach and rather choose the override because with the delegates it makes it harder to add decoration if that is all you need in your child classes.


This is how the outer class can serve as a strategy to the inner service class.

Note that using pattern names such as TemplateMethod and Strategy as real class names is not recommended, use whatever is meaningful in the domain. Same applies to Outer and Inner.

public class Consumer
{
    public void Foo()
    {
        IOuterFoo fooService = new Derived();
        fooService.OuterFoo();
    }
}

// ...

public interface IOuterFoo
{
    void OuterFoo();
}

abstract class Base : Base.IStrategy, IOuterFoo
{
    public void OuterFoo() { _service.Foo(); }

    private readonly InnerService _service;

    protected Base() { _service = new InnerService(this); }

    private interface IStrategy { void Foo(); }

    private class InnerService
    {
        private readonly IStrategy _strategy;
        public InnerService(IStrategy strategy) { _strategy = strategy; }
        public void Foo() { _strategy.Foo(); }
    }

    void IStrategy.Foo() { TemplateMethodFoo(); }

    protected abstract void TemplateMethodFoo();
}

class Derived : Base
{
    protected override void TemplateMethodFoo()
    {
        throw new NotImplementedException();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜