zoukankan      html  css  js  c++  java
  • [札记]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
    

      

  • 相关阅读:
    学习笔记81—matlab通过界面按钮查看回调函数
    学习笔记80—火狐设置
    学习笔记79—几个典型的距离
    学习笔记78—三大统计相关系数:Pearson、Spearman秩相关系数、kendall等级相关系数
    Xcode7修改模块生成网络权限(ATS配置)
    关于解决“No matching provisioning profiles found”问题-ios
    There was a problem parsing the package(android)
    SDK does not contain any platforms. error (android)
    Objective-C中的instancetype与id的区别
    iOS动画编程
  • 原文地址:https://www.cnblogs.com/xingluzhe/p/4727112.html
Copyright © 2011-2022 走看看