C#:有没有办法跳过多态性中的一个基本调用?

C#:有没有办法跳过多态性中的一个基本调用?,c#,inheritance,polymorphism,overriding,virtual-functions,C#,Inheritance,Polymorphism,Overriding,Virtual Functions,正如上面的代码所示,如何让Child.Foo()调用GrandParent.Foo(),而不是调用Parent.Foo()base.Foo()首先带我到父类。如果您可以控制代码,最简单的方法是在父类中创建一个只调用base.Foo()的受保护方法,并且您的子类Foo实现显式调用该方法。不,这是不可能的。想象一下,如果这是可能的话,事情会变得多么疯狂 如果您希望在子< /代码>案例中跳过特定的内容,请考虑重新设计您的设计以更好地表示您需要的内容(例如,您可能需要在子< /代码>类中重写其他内容)。

正如上面的代码所示,如何让Child.Foo()调用GrandParent.Foo(),而不是调用Parent.Foo()
base.Foo()
首先带我到父类。

如果您可以控制代码,最简单的方法是在父类中创建一个只调用base.Foo()的受保护方法,并且您的子类Foo实现显式调用该方法。

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


如果您希望在子< /代码>案例中跳过特定的内容,请考虑重新设计您的设计以更好地表示您需要的内容(例如,您可能需要在子< /代码>类中重写其他内容)。或者,您可以在

父类中提供另一个
Foo()
,它除了调用它的
base.Foo()
否之外什么都不做。它无论如何都不可靠。作为类的实现者,您可以选择直接的基类。但是谁能说以后发行的
Parent
可能不会继承自
ParentBase
,而ParentBase又会继承自
祖父母
?只要
Parent
仍在实现正确的契约,这就不会导致从
Parent
继承的类出现任何问题,我认为您的设计有问题。本质上,您希望“打破”多态性规则。您是说
Child
应该派生自
Parent
,但希望方便地跳过其父级中的实现


重新思考你的设计。

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

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

在一个大型项目中,我们正是在这个场景中从不同的位置调用派生方法的。由于变更管理和QA脚本不会被破坏,在其他约束中,“剧烈”重构和类重组在大型成熟项目中并不总是可能的。此外,我们不希望重写该方法并排除所有基本功能。其他地方看到的大多数解决方案看起来有点笨拙,但来自的解决方案非常有用

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


所有这些强烈的意见

有时候使用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();
  }
}

我确信.net运行时支持这一点。相关阅读也许如果你说明为什么要这样做,我们可以帮助你重新设计你的架构?@CodeInChaos:即使它被支持,也会导致混乱。你需要让
祖父母
抽象
,这样才能工作。编译此代码告诉您,
'GrandParent.DoFoo()是抽象的,但它包含在非抽象类'GrandParent'中。

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.
    }
}   
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();
  }
}