6

I've searched and not been able to find any solution to my problem. My scenario is very simple:

public class A
{
    public virtual void MethodOne()
    {
       Console.log( "A" ); 
    }
}

public class B : A
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.log( "B" );
    }
}

public class C : B
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.log( "C" );
    }
}

What I am trying to do is have an instance of class C (we'll name it 'instanceC') call both the overridden method of its parent, and its grandparent. So I'd expect this:

instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"

But instead am getting this:

instanceC.MethodOne();
// Output
// "A"
// "C"

with class B's method being skipped over. Is this not possible? I thought this is the whole point of inheritance/polymorphism. Thanks in advance!

4

2 回答 2

11

您的示例对我来说按预期工作。我看到 AB C。我认为您最可能的问题是 C 没有扩展 B。但是,在我们讨论这个主题时,让我提出一个可以说更安全的模式。您似乎希望 MethodOne 的所有覆盖都从其基类执行代码。太好了,继承是一个很好的模式。但是,使用这种模式,您无法强制继承者执行基本逻辑,因为您无法强制它们调用base.MethodOne(). 即使他们确实调用base.MethodOne()了,您也无法确保逻辑的顺序。他们会打电话吗base.MethodOne()在方法的开头、方法的中间还是方法的结尾?通常,在这些类型的模式中,您希望子类在函数的开头执行所有基本逻辑。以下模式强制继承者按照基类期望的顺序执行基本逻辑。它在技术上不太灵活但更安全,因为继承者必须以基类指定的方式扩展基类。

public class A
{
    //Don't make this method virtual because you don't actually want inheritors 
    //to be able to override this functionality.  Instead, you want inheritors
    //to be able to append to this functionality.
    public void MethodOne()
    {
        Console.WriteLine( "A" ); 
        MethodToBeOverriddenOne();
    }
    //Expose a place where inheritors can add extra functionality
    protected virtual void MethodToBeOverriddenOne() { }      
}

public class B : A
{
    //Seal the method because you don't actually want inheritors 
    //to be able to override this functionality.  Instead, you want inheritors
    //to be able to append to this functionality.
    protected sealed override void MethodToBeOverriddenOne()
    {
        Console.WriteLine("B");
        MethodToBeOverriddenTwo();
    }
    //Expose a place where inheritors can add extra functionality
    protected virtual void MethodToBeOverriddenTwo() { }  
}

public class C : B
{
    protected sealed override void MethodToBeOverriddenTwo()
    {
        Console.WriteLine("C");
    }
}
于 2013-05-04T18:55:52.920 回答
2

您发布的示例完美运行,无论您在实际代码中做什么都与您发布的不同。

这是您在 ideone 上运行的代码,完全符合您的要求。

using System;

public class Test
{
        public static void Main()
        {
                var c = new C();
                c.MethodOne();
        }
}

public class A
{
    public virtual void MethodOne()
    {
       Console.WriteLine( "A" ); 
    }
}

public class B : A
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.WriteLine( "B" );
    }
}

public class C : B
{
    public override void MethodOne()
    {
        base.MethodOne();
        Console.WriteLine( "C" );
    }
}
于 2013-05-04T18:47:01.080 回答