2013-05-14 22 views
5

在C#中,类A包含公共方法Foo(),它执行一些处理并返回一个值。 protected方法Bar(),也在类A执行与Foo()相同的逻辑,然后进行一些额外的处理,然后返回一个值。调用基本方法而不是覆盖

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

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继承并重写Foo()。覆盖调用基类实现Bar()

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

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

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

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

(我几乎可以肯定是太聪明在这里,这正好完全针对多态,但我无法抗拒的冲动,尝试推动我所知远一点。)

回答

7

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

不直接。最简单的重构是改变Foo到:

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

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

然后换Bar调用FooImpl而不是Foo

(这可能是你在你的“最明显的解决方案”段落的意思 - 我错过了一读,我怕)

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

+0

谢谢,我认为这是最好的/明显的方法。只是想知道我是否可能错过了另一种选择。 – ThatBlairGuy 2013-05-14 17:00:39

+1

@ThatBlairGuy:对不起,我设法错过了描述这个问题的答案。哎呀:)但不,这就是你可以做的一切。 – 2013-05-14 17:02:42

+0

不用担心,谢谢你验证我没有看到什么。 – ThatBlairGuy 2013-05-14 17:15:13