覆盖嵌套的类函数或使用委托?**

时间:2011-04-25 00:52:58

标签: c# class oop nested

我有一个base class,里面有嵌套类型。外部(基础)类型中有一个函数,稍后会被它的子项覆盖。实际上,此函数属于inner type预测的OO,但我仍然需要它,被subtypes的{​​{1}}覆盖。

我应该将此功能用作base class中的callback,还是仅将其移至inner type内,然后让inner type从那里覆盖它?

编辑:已添加示例代码

subtypes

4 个答案:

答案 0 :(得分:2)

我的建议是为基类的构造函数启动的内部类型函数创建一个委托:

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();
    }
}

如您所见,派生类型可以使用:base (overridenAction)调用基本构造函数,在这里它们可以为最内层类型提供自己的函数实现。当然,您没有义务使用Action,而是使用您想要的任何代表。

答案 1 :(得分:1)

IMO您所描述的内容如The Strategy design pattern。考虑使用这种模式。您的代码将更易于维护,因为它包含可识别的模式。您还可以查看state design pattern,通常您必须在这两者之间进行选择,它们是紧密相连的。

答案 2 :(得分:1)

在这种情况下:

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

您无法从课程A派生并覆盖课程func()中的B

根据您的描述,似乎A派生类应该能够覆盖内部类B中的某些功能(或功能),这表明您可能应该重新考虑您的设计。要么提取B并且不要使它成为内部类,要么通过这样的接口使您想要覆盖显式依赖的功能:

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

无论如何,如果你想坚持你的设计,那么我不建议使用委托方法,而是选择覆盖,因为如果在你的子课程中只需要这些,那么就更难添加装饰。

答案 3 :(得分:1)

这就是外部类可以作为内部服务类策略的方式。

请注意,建议不要使用TemplateMethodStrategy等模式名称作为实际类名,请使用域中有意义的内容。同样适用于OuterInner

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();
    }
}