C# 未调用具有多级继承的base.Method()?
我一直在寻找,没有找到任何解决我问题的办法。我的情况非常简单:C# 未调用具有多级继承的base.Method()?,c#,.net,inheritance,base-class,C#,.net,Inheritance,Base Class,我一直在寻找,没有找到任何解决我问题的办法。我的情况非常简单: 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 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" );
}
}
我试图做的是让C类的一个实例(我们将其命名为“instanceC”)调用其父类和其父类的重写方法。所以我希望:
instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"
但我得到的是:
instanceC.MethodOne();
// Output
// "A"
// "C"
跳过类B的方法。这不可能吗?我认为这就是遗传/多态性的全部要点。提前谢谢 您发布的示例非常有效,无论您在实际代码中做什么,都与您发布的不同 像你想的那样工作
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" );
}
}
你的例子对我来说很有效。我看到了一个B 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");
}
}
你确定C来自B而不是A吗?为什么C来自B?您希望它继承自A。您的示例对我来说正如预期的那样工作,并打印“A B C”,同样对我来说,您的示例工作正常,您的原始文档中一定有缺失或错误code@Derek如果需要执行B的某些行为,但需要在调用之前或之后添加其他行为。有一次,由于XmlReader的原因,我不得不重写FileStream。我能够重写GetBytes,调用
base.GetBytes
从FileStream获取结果,将无效值更改为替换字符,然后将其传递给XmlReader。Create
这是一个比另一个更好的答案,因为它清楚地显示了如何确保始终调用基本方法。不知道为什么被否决。我睡得很少,你们是对的;C愚蠢地扩展了A而不是C。所以,虽然这确实是个问题,但我确实认为这是一个更好的解决方案,而且我有很好的结果。非常感谢。不是我投了反对票,我认为这也比我的好,并给了它一个+1个我知道的老问题,但我只是想补充一点,如果这是你想要的,这显然是一个很好的模式。如果您需要客户机能够禁用基类功能(并实际覆盖它),那么这不是一条可行的道路。当然,您首先要调用base.MethodOne()
。