代码之家  ›  专栏  ›  技术社区  ›  mackenir

如何调用重写虚拟方法的“基本实现”?[副本]

  •  60
  • mackenir  · 技术社区  · 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...
      }
    
    6 回复  |  直到 12 年前
        1
  •  144
  •   Pete    9 年前

    使用C#语言构造,无法从中显式调用基函数 外部 A 或 B . 如果您真的需要这样做,那么您的设计中就存在一个缺陷,即该函数一开始不应该是虚拟的,或者应该将基本函数的一部分提取到一个单独的非虚拟函数中。

    你可以从 在…内 B.X.但是叫A.X

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

    但那是另外一回事。

    this answer ,你可以通过IL来完成。 正如mhand在评论中指出的那样,您也可以通过反思来完成它。

        2
  •  13
  •   Sasha Truf    10 年前

    你不能用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 
    }
    

    您应该将L_0008中的操作码从 卡尔维特 到 呼叫

    L_0008: call instance void MsilEditing.A::X()
    
        3
  •  9
  •   John Feminella    17 年前

    您可以这样做,但不是在您指定的点。在 B ,您可以调用 A.X() base.X() .

        4
  •  8
  •   Jorge Córdoba    17 年前

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

        5
  •  8
  •   Zohar Peled    11 年前

    如果该方法在派生类中声明为 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();
    a.X(); // returns Derived 1
    b.X(); // returns Base
    c.X(); // returns Derived 2
    

    See fiddle here

        6
  •  6
  •   lkuder    12 年前

    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();
    
    
      }