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

发布于 2024-11-27 09:45:40 字数 504 浏览 1 评论 0原文

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 类。

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

As the code above shows, how can I have the Child.Foo() make a call into GrandParent.Foo() instead of going into Parent.Foo()? base.Foo() takes me to the Parent class first.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

滥情空心 2024-12-04 09:45:40

如果你需要这个,你的设计就是错误的。
相反,请将每个类的逻辑放在 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)
    }
}

Your design is wrong if you need this.
Instead, put the per-class logic in DoFoo and don't call base.DoFoo when you don't need to.

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)
    }
}
全部不再 2024-12-04 09:45:40

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

重新思考你的设计。

I think there is something wrong with your design here. Essentially, you want to "break" the rules of polymorphism. You are saying Child should derive from Parent but want to conveniently skip the implementation in it's parent.

Re-think your design.

黑凤梨 2024-12-04 09:45:40

不,无论如何这都不可靠。作为您的类的实现者,您可以选择您的直接基类。但谁说 Parent 的更高版本可能不会从 ParentBase 继承,而后者又从 GrandParent 继承呢?只要 Parent 仍然实现正确的契约,这就不会对那些继承自 Parent 的类造成任何问题。

No. It wouldn't be reliable anyway. You, as the implementer of your class, get to choose your immediate base class. But who is to say that a later release of Parent might not inherit from ParentBase, that in turn inherits from GrandParent? So long as Parent is still implementing the correct contract, this should not cause any issues for those classes inheriting from Parent.

走过海棠暮 2024-12-04 09:45:40

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

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

No, this isn't possible. Imagine how crazy things would be if this was possible.

If you want something specific skipped in the Child case, consider reworking your design to better represent what you need (e.g. maybe you need to override something else in the Child class, too). Or, you could provide another Foo() in the Parent class that doesn't do anything except call its base.Foo().

牵你的手,一向走下去 2024-12-04 09:45:40

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

If you have control of the code, the simplest way is to create a protected method in Parent class that only call base.Foo() and your child class Foo implementation call that method explicitly

怂人 2024-12-04 09:45:40

我们在一个大型项目中遇到过这种情况,其中派生方法是从不同位置调用的。由于变更管理和 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.
    }
}   

We had exactly this scenario on a large project where the derived methods were called from various locations. Due to change management and QA scripts not to be broken, among other constraints, "drastic" refactoring and class re-structuring are not always possible on a large mature project. Also we did not want to override the method and exclude all base functionality. Most solutions seen elsewhere, looked a bit clumsy, but the solution from Josh Jordan on How to call base.base was quite useful.

However we followed the approach below (which I see now is very similar to what Dan Abramov propose).

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

旧街凉风 2024-12-04 09:45:40

所有这些强烈的意见...

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

All these strong opinions...

Sometimes it just makes sense to use 99% of something...

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();
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文