[札记]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
[札记]IL经典指令解析之方法调度的更多相关文章
- IL中间语言指令大全
一些 IL 语言指令解释: Public field Static Beq 如果两个值相等,则将控制转移到目标指令.Public field Static Beq_S ...
- AngularJS 指令解析(二)
AngularJS 指令解析(二) 第一篇我们讲过了作用域(scope)这块内容,现在我们进入正题,讲AngularJS的指令. 什么是指令? 这里我们引用官方的一句话: Custom directi ...
- AngularJS 指令解析(一)
AngularJS 指令解析(一) 前言 笔者AngularJS接触时间差不多是两年多,虽然这两年多AngularJS版本日新月异,但是笔者的版本是比较老的1.4.3,一方面是自己对这个版本比较熟悉, ...
- .NET中常用的几种解析JSON方法
一.基本概念 json是什么? JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是一种轻量级的数据交换格式,是存储和交换文本信息的语法. ...
- Java学习笔记之方法重载,动态方法调度和抽象类
一.方法重载 如果子类中的方法与它的超类中的方法有相同的方法名,则称子类中的方法重载超类中的方法,特别是当超类和子类中的方法名和参数类型都相同时,在子类中调用该方法时,超类中的方法会被隐藏.考虑下面程 ...
- C# 解析js方法,并调用js方法
本文转载:http://www.cnblogs.com/StudyLife/archive/2013/03/11/2953516.html 本文不是基于B/S的 后台调用前台js方法,而是给你一段js ...
- 017——VUE中v-fo指令的使用方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Dockerfile的书写规则和指令的使用方法
Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令.Docker程序将这些Dockerfile指令翻译真正的Linux命 ...
- securecrt中进入uboot命令行时,出现无法键入任何指令的问题解决方法
securecrt中进入uboot命令行时,出现无法键入任何指令的问题解决方法 可能出现以下几种情况 1.securecrt在创建连接时,忘记取消勾选流控: 2.usb转串口线坏了3.uboot有问题 ...
随机推荐
- boot.img的分析
1 boot.img boot.img是由文件头信息,内核数据以及文件系统数据组成,它们之间非页面对齐部分用0填充 文件头信息的具体结构可以在system/core/mkbootimg/bootim ...
- 【Python】如何安装easy_install?
[Python]如何安装easy_install? http://jingyan.baidu.com/article/b907e627e78fe146e7891c25.html easy_instal ...
- JSON 之 SuperObject(8): 关于乱码的几种情况 - 向 Henri Gourvest 大师报告
这几天学习 JSON - SuperObject, 非常幸运地得到了其作者 Henri Gourvest 大师的同步指点! (Henri 大师也是 DSPack 和 GDI+ 头文件的作者; 大师是法 ...
- 函数lock_rec_get_first_on_page
lock结构体 详见 /*********************************************************************//** Gets the first ...
- Eclipse使用代码清理功能(Clean Up)
本文转载自http://www.ibm.com/developerworks/cn/opensource/os-eclipse-clean/ 但是为了适应自己使用,还是自己总结了一下. 一.概述 代码 ...
- 无线端通用的reset样式
@charset "utf-8"; html, body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, o ...
- php 获取301 302的真实地址
function getRealURL($url){ $header = get_headers($url,1); if (strpos($header[0],'301') || strpos($he ...
- 【Python】入门 list有些不懂
# -*- coding: utf-8 -*- # -*- coding: cp936 -*- 首行加这个 代码里就可以加注释 raw_input("Press Enter Exit&quo ...
- 嵌入式 Linux下curl库API简单介绍
1:CURLcode curl_global_init(long flags); 这个函数全局需要调用一次(多次调用也可以,不过没有必要), 所以这也是把Curlplus设计成单体类的原因,curl_ ...
- Android Service 服务
一. Service简介 Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver.ContentProvider),它跟Activi ...