• [札记]IL经典指令解析之方法调度


    call、callvirt和calli指令用于完成方法调用,有何区别呢?

    1)call使用静态调度,也就是根据引用类型的静态类型来调度方法。call指令根据引用变量的类型来调用方法,因此通常用于调用非虚方法。

    2)callvirt使用虚拟调度,也就是根据引用类型的动态类型来调度方法;callvirt指令根据引用变量指向的对象类型来调用方法,执行时会递归的调用给自己知道堆栈溢出,从而实现了在运行时的动态绑定,因此通常用于调用虚方法。

    3)calli又称间接调用,是通过函数指针来执行方法调用的。与call和callvirt相对应的(直接调用)

     Father类

    public class Father
        {
            public void DoWork()
            {
                Console.WriteLine("Father.DoWork()");
            }
    
            public virtual void DoVirtualWork()
            {
                Console.WriteLine("Father.DoVirtualWork()");
            }
    
            public virtual void DoVirtualAll()
            {
                Console.WriteLine("Father.DoVirtualAll()");
            }
        }
    

    Son类

    public class Son:Father
        {
            public static void DoStaticWork()
            {
                Console.WriteLine("Son.DoStaticWork()");
            }
    
            public new void DoWork()//new表示对父类的阻断
            {
                Console.WriteLine("Son.DoWork()");
            }
    
            public new virtual void DoVirtualWork()
            {
                Console.WriteLine("Son.DoVirtualWork()");
            }
    
            public override void DoVirtualAll()
            {
                base.DoVirtualAll();
                Console.WriteLine("Son.DoVirtualAll()");
            }
        }
    

    GrandSon类

    public class GrandSon:Son
        {
            public override void DoVirtualWork()
            {
                base.DoVirtualWork();
                Console.WriteLine("GrnadSon.DoVirtualWork()");
            }
    
            public override void DoVirtualAll()
            {
                base.DoVirtualAll();
                Console.WriteLine("GrandSon.DoVirtualAll()");
            }
        }
    

    Prgram.cs

    class Program
        {
            static void Main(string[] args)
            {
                Father son = new Son();
                son.DoWork();
                son.DoVirtualWork();
    
                Son.DoStaticWork();
    
                Father aGrandSon = new GrandSon();
                aGrandSon.DoWork();
                aGrandSon.DoVirtualWork();
                aGrandSon.DoVirtualAll();
    
                Console.ReadLine();
            }
        }
    

    输出结果  

      

    IL代码

    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // 代码大小       61 (0x3d)
      .maxstack  1
      .locals init ([0] class ConsoleApplication1.Father son,
               [1] class ConsoleApplication1.Father aGrandSon)
      IL_0000:  nop
      IL_0001:  newobj     instance void ConsoleApplication1.Son::.ctor()
      IL_0006:  stloc.0
      IL_0007:  ldloc.0
      IL_0008:  callvirt   instance void ConsoleApplication1.Father::DoWork()
      IL_000d:  nop
      IL_000e:  ldloc.0
      IL_000f:  callvirt   instance void ConsoleApplication1.Father::DoVirtualWork()
      IL_0014:  nop
      IL_0015:  call       void ConsoleApplication1.Son::DoStaticWork()
      IL_001a:  nop
      IL_001b:  newobj     instance void ConsoleApplication1.GrandSon::.ctor()
      IL_0020:  stloc.1
      IL_0021:  ldloc.1
      IL_0022:  callvirt   instance void ConsoleApplication1.Father::DoWork()
      IL_0027:  nop
      IL_0028:  ldloc.1
      IL_0029:  callvirt   instance void ConsoleApplication1.Father::DoVirtualWork()
      IL_002e:  nop
      IL_002f:  ldloc.1
      IL_0030:  callvirt   instance void ConsoleApplication1.Father::DoVirtualAll()
      IL_0035:  nop
      IL_0036:  call       string [mscorlib]System.Console::ReadLine()
      IL_003b:  pop
      IL_003c:  ret
    } // end of method Program::Main
    

      

  • 相关阅读:
    legend3---videojs存储视频的播放速率便于用户观看视频
    legend3---mathjax的动态渲染问题解决
    matplotlib库疑难问题---10、画直方图
    matplotlib库疑难问题---9、画箭头(综合实例)
    js释放图片资源
    javascript中的原型与原型链
    前端跨域方式
    matplotlib清除 axes 和 figure
    matplotlib画直方图细解
    CentOS 7.8 安装 Python 3.8.5
  • 原文地址:https://www.cnblogs.com/xingluzhe/p/4727112.html
Copyright © 2020-2023  润新知