C#:有什么方法可以跳过多态中的一个基本调用?

class GrandParent { public virtual void Foo() { ... } } class Parent : GrandParent { public override void Foo() { base.Foo(); //Do additional work } } class Child : Parent { public override void Foo() { //How to skip Parent.Foo and just get to the GrandParent.Foo base? //Do additional work } } 

如上面的代码所示,我如何让Child.Foo()调用GrandParent.Foo()而不是进入Parent.Foo()? base.Foo()将我带到Parent类。

如果你需要,你的设计是错误的。
相反,将每类逻辑放在DoFoo并且在不需要时不要调用base.DoFoo

 class GrandParent { public void Foo() { // base logic that should always run here: // ... this.DoFoo(); // call derived logic } protected virtual void DoFoo() { } } class Parent : GrandParent { protected override void DoFoo() { // Do additional work (no need to call base.DoFoo) } } class Child : Parent { protected override void DoFoo() { // Do additional work (no need to call base.DoFoo) } } 

我认为你的设计有问题。 从本质上讲,您希望“打破”多态的规则。 你说Child应该从Parent派生,但是想要方便地跳过它的父实现。

重新考虑你的设计。

不,无论如何它都不可靠。 作为class级的实施者,您可以选择直接的基类。 但是谁会说Parent的后续版本可能不会inheritanceParentBase ,而inheritance自GrandParent ? 只要Parent仍在实现正确的合同,这不应该导致从Parentinheritance的那些类的任何问题。

不,这是不可能的。 想象一下如果可能的话会有多疯狂。

如果您想要在Child案例中跳过某些特定内容,请考虑重新设计您的设计以更好地表示您需要的内容(例如,您可能需要覆盖Child类中的其他内容)。 或者,您可以在Parent类中提供另一个Foo() ,除了调用它的base.Foo()之外不会执行任何操作。

如果你能控制代码,最简单的方法是在Parent类中创建一个只调用base.Foo()的受保护方法,你的子类Foo实现调用该方法

我们在一个大型项目中确实有这种情况,从各个位置调用派生方法。 由于变更管理和QA脚本不被破坏,除了其他限制之外,在大型成熟项目中并不总是能够进行“激烈”的重构和类重构。 此外,我们不想覆盖该方法并排除所有基本function。 在其他地方看到的大多数解决方案看起来有点笨拙,但Josh Jordan关于如何调用base.base的解决方案非常有用。

然而,我们遵循以下方法(我现在看到的与Dan Abramov提出的非常类似)。


 public class Base { public virtual void Foo() { Console.WriteLine("Hello from Base"); } } public class Derived : Base { public override void Foo() { base.Foo(); Console.WriteLine("Text 1"); WriteText2Func(); Console.WriteLine("Text 3"); } protected virtual void WriteText2Func() { Console.WriteLine("Text 2"); } } public class Special : Derived { public override void WriteText2Func() { //WriteText2Func will write nothing when method Foo is called from class Special. //Also it can be modified to do something else. } }