5

在 C# 中,类A包含一个公共方法Foo(),该方法进行一些处理并返回一个值。 protected方法Bar(),也在类中A执行与 相同的逻辑Foo(),然后进行一些额外的处理,然后返回一个值。

为了避免重复代码,Bar()调用Foo()并使用返回值作为中间值。

class A
{
  public virtual String Foo()
  {
     String computedValue;
     // Compute the value.
     return computedValue;
  }

  protected String Bar()
  {
     String computedValue;
     String intermediateValue = Foo();
     /// More processing to create computedValue from intermediateValue.
     return computedValue;
  }
}

B继承A并覆盖Foo(). 覆盖调用 的基类实现Bar()

class B : A
{
   public override String Foo()
   {
     base.Bar();
   }
}

这(当然)进入无限循环,直到计算机内存不足,然后产生堆栈溢出异常。

最明显的解决方案是使用FooInternals包含 Foo 内容的私有方法重写 A。然后修改 Foo 和 Bar 以使用该方法的结果。

有没有办法强制 ABar()调用 AFoo()而不是覆盖?

(我几乎可以肯定在这里太聪明了;这完全违背了多态性。但我无法抗拒尝试进一步推动我的知识的冲动。)

4

1 回答 1

7

有没有办法强制 A 的 Bar() 调用 A 的 Foo() 而不是覆盖?

不是直接的。最简单的重构将更Foo改为:

public virtual string Foo()
{
    return FooImpl();
}

private string FooImpl()
{
    String computedValue;
    // Compute the value.
    return computedValue;
}

然后更改Bar为 callFooImpl而不是Foo.

(这可能是您在“最明显的解决方案”段落中的意思——恐怕我在第一次阅读时错过了。)

从根本上说,这只是继承存在问题的领域之一。当一个虚拟方法调用另一个虚拟方法时,需要记录下来,以便子类可以避免引起问题——即使感觉它应该是一个实现细节。正是这种事情让我更喜欢组合而不是继承——当然,两者都是合理的选择。

于 2013-05-14T16:58:49.920 回答