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.
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 fromParent
but want to conveniently skip the implementation in it's parent.Re-think your design.
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).
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
Your design is wrong if you need this.
Instead, put the per-class logic in
DoFoo
and don't callbase.DoFoo
when you don't need to.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 theChild
class, too). Or, you could provide anotherFoo()
in theParent
class that doesn't do anything except call itsbase.Foo()
.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 fromParentBase
, that in turn inherits fromGrandParent
? So long asParent
is still implementing the correct contract, this should not cause any issues for those classes inheriting fromParent
.