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

  

[札记]IL经典指令解析之方法调度的更多相关文章

  1. IL中间语言指令大全

    一些 IL 语言指令解释: Public field Static     Beq     如果两个值相等,则将控制转移到目标指令.Public field Static     Beq_S     ...

  2. AngularJS 指令解析(二)

    AngularJS 指令解析(二) 第一篇我们讲过了作用域(scope)这块内容,现在我们进入正题,讲AngularJS的指令. 什么是指令? 这里我们引用官方的一句话: Custom directi ...

  3. AngularJS 指令解析(一)

    AngularJS 指令解析(一) 前言 笔者AngularJS接触时间差不多是两年多,虽然这两年多AngularJS版本日新月异,但是笔者的版本是比较老的1.4.3,一方面是自己对这个版本比较熟悉, ...

  4. .NET中常用的几种解析JSON方法

    一.基本概念 json是什么? JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是一种轻量级的数据交换格式,是存储和交换文本信息的语法. ...

  5. Java学习笔记之方法重载,动态方法调度和抽象类

    一.方法重载 如果子类中的方法与它的超类中的方法有相同的方法名,则称子类中的方法重载超类中的方法,特别是当超类和子类中的方法名和参数类型都相同时,在子类中调用该方法时,超类中的方法会被隐藏.考虑下面程 ...

  6. C# 解析js方法,并调用js方法

    本文转载:http://www.cnblogs.com/StudyLife/archive/2013/03/11/2953516.html 本文不是基于B/S的 后台调用前台js方法,而是给你一段js ...

  7. 017——VUE中v-fo指令的使用方法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Dockerfile的书写规则和指令的使用方法

    Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令.Docker程序将这些Dockerfile指令翻译真正的Linux命 ...

  9. securecrt中进入uboot命令行时,出现无法键入任何指令的问题解决方法

    securecrt中进入uboot命令行时,出现无法键入任何指令的问题解决方法 可能出现以下几种情况 1.securecrt在创建连接时,忘记取消勾选流控: 2.usb转串口线坏了3.uboot有问题 ...

随机推荐

  1. H5移动前端完美布局之padding

    序上次的提到了H5移动前端完美布局之-margin百分比的使用margin-top(left,right,bottom)的百分比在移动页面布局中对上下左右距离的处理,攻下城外再攘城内,今天看看padd ...

  2. [HIHO1039]字符消除(字符串,枚举,模拟)

    题目链接:http://hihocoder.com/problemset/problem/1039 思路:枚举所有字符更新的位置和ABC三种修改方案,之后再模拟消除规则,一步一步去消除.直到无法消除, ...

  3. [HDOJ5521]Meeting(最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521 给n个点,m个块.块内点到点之间话费的时间ti.两个人分别从点1和点n出发,问两人是否可以相遇, ...

  4. 总结Selenium自动化测试方法(六)常见的异常错误处理

    六.常见的异常错误处理 NoSuchElementException: Message: Unable to locate element: {"method":"xpa ...

  5. leetcode:Excel Sheet Column Number

    Given a column title as appear in an Excel sheet, return its corresponding column number. For exampl ...

  6. [ionic开源项目教程] - 第10讲 新闻详情页的用户体验优化

    目录 [ionic开源项目教程] 第1讲 前言,技术储备,环境搭建,常用命令 [ionic开源项目教程] 第2讲 新建项目,架构页面,配置app.js和controllers.js [ionic开源项 ...

  7. UVa 11014 (莫比乌斯反演) Make a Crystal

    这个题是根据某个二维平面的题改编过来的. 首先把问题转化一下, 就是你站在原点(0, 0, 0)能看到多少格点. 答案分为三个部分: 八个象限里的格点,即 gcd(x, y, z) = 1,且xyz均 ...

  8. mysql应用存储过程批量插入数据

    --批量插入数据的sql语句 delimiter $$ DROP PROCEDURE IF EXISTS `test.sp_insert_batch` $$ CREATE DEFINER =`root ...

  9. 【C#学习笔记】Hello World

    using System; namespace ConsoleApplication { class Program { static void Main(string[] args) { Conso ...

  10. ecshop 无限分类解析(转)

    对ecshop无限级分类的解析,认真分析后发现真的其算法还是比较精典的其实并不难理解,有举例方便大家理解 function cat_options($spec_cat_id, $arr) { stat ...