C#:跳过多态性中的一个基本调用的任意方法

本文关键字:一个 方法 任意 调用 多态性 | 更新日期: 2023-09-27 18:04:21

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()首先将我带到父类。

C#:跳过多态性中的一个基本调用的任意方法

如果你需要这个,你的设计是错误的。
相反,将每类逻辑放在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派生,但想方便地跳过其父级中的实现。

重新思考您的设计。

No.反正也不靠谱。作为类的实现者,您可以选择直接基类。但是谁能说后来的Parent版本可能不会继承ParentBase,而这反过来又继承了GrandParent?只要Parent仍在实现正确的协定,这应该不会给那些从Parent继承的类带来任何问题。

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

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

如果您可以控制代码,最简单的方法是在 Parent 类中创建一个仅调用 base 的受保护方法。Foo(( 和你的子类 Foo 实现显式调用该方法

我们在一个

大型项目中正是这样,其中派生方法是从不同位置调用的。由于变更管理和QA脚本不能被破坏,以及其他限制,在一个大型成熟项目中,"剧烈"重构和类重组并不总是可能的。此外,我们不想覆盖该方法并排除所有基本功能。在其他地方看到的大多数解决方案看起来有点笨拙,但Josh Jordan关于如何调用base.base的解决方案非常有用。

然而,我们遵循了下面的方法(我现在看到的方法与丹·阿布拉莫夫提出的非常相似(。

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.
    }
}   

所有这些

强烈的意见...

有时使用 99% 的东西是有意义的......

public class Base
{
  public virtual void Foo()
  {
   // Do something
  }
}
public class DerivedLevel1 : Base
{
  public override void Foo()
  {
    DerivedLevel1Foo();
  }
  protected void DerivedLevel1Foo()
  {
    // Do something
    base.Foo();
  }
}
public class DerivedLevel2 : DerivedLevel1
{
  public override void Foo()
  {
   DerivedLevel2Foo();
  }
  protected void DerviedLevel2Foo()
  {
    // Do something
    base.Foo();
  }
}
public class Special : Derived
{
  public override void Foo()
  {
    // Don't do DerivedLevel2Foo()
    base.DerivedLevel1Foo();
  }
}