如何调用重写的虚方法的“基实现”?

给定以下代码,有没有一种方法可以调用类 A 的方法 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...
}
142384 次浏览

你不能,也不应该。这就是多态性的用途,因此每个对象都有自己的方式来做一些“基本”事情。

您可以这样做,但不能在您指定的时间点。在 B的上下文中,可以通过调用 base.X()来调用 A.X()

Using the C# language constructs, you cannot explicitly call the base function from 在外面 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 在里面 B.X however call A.X

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

但那是另一回事。

正如 Sasha Truf 在 这个答案中指出的,你可以通过 IL 来完成。 正如 mhand 在评论中指出的那样,您也可以通过反射来完成它。

I konow it's history question now. But for other googlers: you could write something like this. But this requires change in base class what makes it useless with external libraries.

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


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




}

你不能用 C # 来做,但是你可以编辑 MSIL。

总部方法的 IL 代码:

.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 打电话

L_0008: call instance void MsilEditing.A::X()

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

看这里