Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call the 'base implementation' of an overridden virtual method? [duplicate]

Tags:

c#

oop

Given the following code, is there a way I can call class A's version of method X?

class A
{
  virtual void X() { Console.WriteLine("x"); }
}

class B : A
{
  override void X() { Console.WriteLine("y"); }
}

class Program
{
  static void Main()
  {
    A b = new B();
    // Call A.X somehow, not B.X...
  }
like image 459
mackenir Avatar asked Aug 26 '09 12:08

mackenir


People also ask

How do you call a base class overridden method?

Invoking overridden method from sub-class : We can call parent class method in overriding method using super keyword. Overriding and constructor : We can not override constructor as parent and child class can never have constructor with same name(Constructor name must always be same as Class name).

How do you call a virtual method of base class in C++?

When you want to call a specific base class's version of a virtual function, just qualify it with the name of the class you are after, as I did in Example 8-16: p->Base::foo(); This will call the version of foo defined for Base , and not the one defined for whatever subclass of Base p points to.

Can we override already overridden method?

You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.

How to call the overridden method from the Super class?

> If you need to call the overridden method from the super class on an object of a subclass, then most definitely you have structured your program wrong. The calling object should not care about how a method is implemented inside the class of the object. They should just know the signature of the method (Name and the parameters it’s accepting).

Is it bad design to call base methods from overridden methods?

When writing tests, its not unusual to want to modify behavior through polymorphic tricks. As such, needing to call base methods from within a overridden method does not necessarily indicate bad design -- it might indicate design that is hard to test. I came across your answer exactly due to such needs.

Can we call a non overridden method in child class in Java?

Can we call a non overridden method in child class from the object of parent class having reference of child class in Java? No you can’t. Different method name will have a clear intent that this child’s method won’t change parent method Full Stack Developer. Foodie.

What is function overidden in C++?

Function overidden is done so that you can modify a function which is inherited from the parent class and provide specificity to it. So after making changes, you’ve got to call modified version of it. If you want to call the function of A, you must call it directly by making object of A.


3 Answers

Using the C# language constructs, you cannot explicitly call the base function from outside the scope of A or B. If you really need to do that, then there is a flaw in your design - i.e. that function shouldn't be virtual to begin with, or part of the base function should be extracted to a separate non-virtual function.

You can from inside B.X however call A.X

class B : A
{
  override void X() { 
    base.X();
    Console.WriteLine("y"); 
  }
}

But that's something else.

As Sasha Truf points out in this answer, you can do it through IL. You can probably also accomplish it through reflection, as mhand points out in the comments.

like image 168
Pete Avatar answered Oct 08 '22 19:10

Pete


You can't do it by C#, but you can edit MSIL.

IL code of your Main method:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] class MsilEditing.A a)
    L_0000: nop 
    L_0001: newobj instance void MsilEditing.B::.ctor()
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: callvirt instance void MsilEditing.A::X()
    L_000d: nop 
    L_000e: ret 
}

You should change opcode in L_0008 from callvirt to call

L_0008: call instance void MsilEditing.A::X()
like image 14
Sasha Truf Avatar answered Oct 08 '22 19:10

Sasha Truf


It's impossible if the method is declared in the derived class as overrides. to do that, the method in the derived class should be declared as new:

public class Base {

    public virtual string X() {
        return "Base";
    }
}
public class Derived1 : Base
{
    public new string X()
    {
        return "Derived 1";
    }
}

public class Derived2 : Base 
{
    public override string X() {
        return "Derived 2";
    }
}

Derived1 a = new Derived1();
Base b = new Derived1();
Base c = new Derived2();
a.X(); // returns Derived 1
b.X(); // returns Base
c.X(); // returns Derived 2

See fiddle here

like image 11
Zohar Peled Avatar answered Oct 08 '22 19:10

Zohar Peled