我怎样才能调用被重载的虚拟方法的“基础实现”?

给定下面的代码,有没有办法可以调用类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 AX somehow, not BX.. } 

使用C#语言结构,不能从AB的范围之外明确调用基本函数。 如果你确实需要这样做的话,那么你的devise就有一个缺陷 – 即这个函数不应该是虚拟的,或者一部分基本函数应该被提取到一个单独的非虚函数中。

你可以从BX 里面调用AX

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

但那是别的。

正如Sasha Truf在这个答案中指出的,你可以通过IL来做到这一点。 你也可以通过反思来完成它,正如评论中指出的那样。

你不能用C#来完成,但你可以编辑MSIL。

你的Main方法的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 } 

您应该将L_0008中的操作码从callvirt更改call

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

你可以做到这一点,但不是在你指定的地方。 在B的上下文中,你可以通过调用base.X()来调用AX() base.X()

你不能,而你不应该。 这就是多态的目的,所以每个对象都有自己的方式来做一些“基础”的事情。

我现在知道这是历史问题。 但对于其他谷歌:你可以写这样的事情。 但是这需要在基类中进行更改,使其对外部库无用。

 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 AX somehow, not BX.. b.protoX(); } 

如果该方法在派生类中被声明为overrides这是不可能的。 要这样做,派生类中的方法应该声明为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(); aX(); // returns Derived 1 bX(); // returns Base cX(); // returns Derived 2 

在这里看小提琴