How can I call the 'base implementation' of an overridden virtual method?
本问题已经有最佳答案,请猛点这里访问。
给定以下代码,有没有方法可以调用类A的方法X版本?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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... } |
使用C语言结构,不能从
你可以从B.X内部呼叫A.X
1 2 3 4 5 6 7 | class B : A { override void X() { base.X(); Console.WriteLine("y"); } } |
但那是另外一回事。
正如萨沙·特鲁夫在这个答案中指出的那样,你可以通过IL来做到这一点。正如mhand在评论中指出的那样,你也可以通过反思来完成它。
你不能用c来完成,但是你可以编辑msil。
主要方法的IL代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .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
1 | L_0008: call instance void MsilEditing.A::X() |
你可以这样做,但不是在你指定的地方。在
你不能,你也不应该。这就是多态性的目的,所以每个对象都有自己的方式来做一些"基础"的事情。
我知道这是历史问题了。但是对于其他谷歌用户:你可以写这样的东西。但这需要在基类中进行更改,这就使得它不能用于外部库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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(); } |
如果方法在派生类中声明为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 |
在这里看小提琴