专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > CLR

CLR调用静态方法、实例方法跟虚方法的区别

发布时间:2011-06-23 13:51:20 文章来源:www.iduyao.cn 采编人员:星星草
CLR调用静态方法、实例方法和虚方法的区别

[<CLR via C#>学习笔记]

[代码皆来自CLR via C#,有改动]

在解释CLR调用这三种方法的区别之前,先看看c#如何生成程序集的:

这幅图只是为了说明IL中间语言代码和元数据的关系,即通过元数据可以找到类型对应的IL代码

 

接下来看看一个方法被调用时发生的事情:

接下来Main第二次调用Console.WriteLine(string)方法时就不会经过JIT编译器,而是直接执行JIT第一次已经编译好的代码.

CLR之所以可以检测到代码中所有的引用类型,是因为元数据表的引用表记录了源代码中所有的引用类型和成员,而通过这个引用表也就可以获得该方法的IL了,然后JIT编译器也就可以编译这些IL.

 

现在可以开始对比CLR调用静态方法、实例方法和虚方法的区别了:

定义如下两个类:

class Employee
{
    public int GetYearsEmployed(){};
    public virtual string GetProgressReport(){};
    public static Employee Lookup(string name){};
}

class Manager : Employee
{
    public override string GetProgressReport(){};
}

 

现在即将调用以下方法M(),

void M()
{
   Employee e = new Manager();
   e = Employee.Lookup("joe");
   int year = e.GetYearsEmployed();
  e.GetProgressReport(); }

假定CLR即将加载到M方法,托管堆已初始化,已创建一个线程栈,当JIT编译器将M方法转换成本机CPU指令时,注意到M()内部的引用类型,创建两个类型对象

执行第一段代码时是new操作符所干的事,结果如下:

1,调用静态方法:

2,调用非虚实例方法时,

 

3,虚实例方法:

总结:

  1,调用静态方法时,CLR会直接定位到定义静态方法的类型对应的类型对象.然后JIT编译器查找方法表中被调用的静态方法对应的记录项.对方法进行JIT编译.

      如 e = Employee.Lookup("joe"); 则CLR会定位到Employee类型对象.于是代码就在Employee类型对象的方法表中查找引用了被调用的方法的记录项,对方法进行JIT编译(第一次执行的话),再调用编译好的代码.

  2,调用非虚实例方法时,JIT编译器会找到'发出调用的变量的类型'对应的类型对象,查找方法表中被调用的非虚实例方法对应的记录项,对方法进行JIT编译.若找不到该方法则回溯层次结构查找该方法直到Object

      如  int year = e.GetYearsEmployed(); 会找到e的类型对应的类型对象.而申明e的代码为: Employee e = new Manager(); 因此此时e被定义为一个Employee对象.于是代码就在Employee类型对象的方法表中查找该方法,如果未找到则回溯层次结构,并沿途查找该方法直到Object.

  3,调用虚实例方法时,JIT编译器会生成额外的代码,这些代码用来检查发出调用的变量及其在堆中的地址,并且跟随地址来到堆中实际对象.然后代码检查实际对象内部的'类型对象指针',其指向了该实际对象指向的类型对象.查找方法表中被调用的静态方法对应的记录项.对方法进行JIT编译.

      如 e.GetProgressReport(); ,JIT会到堆上的实际对象(根据生成的额外的代码),检查该对象的'类型对象指针',发现它指向了Manager类型对象,于是代码就在Manager类型对象的方法表中查找引用了被调用的方法的记录项,对方法进行JIT编译(第一次执行的话),再调用编译好的代码.

 

  可以发现,调用静态方法直接"跳"到类型对象;类似的调用非虚实例方法会找到类型对象(虽然方法不一定在该类型对象中),而相比调用虚实例方法则要"走"两段路才可以找到类型对象.

  与此同时,Employee和Manager类型对象也是对象,而他们指向System.Type类型创建的一个特殊的类型对象,而System.Type类型对象也是对象,它内部的“类型对象指针”指向它本身  

  System.GetType()方法返回的是“类型对象指针”中指向的地址

  然而,讨论CLR调用静态方法、实例方法和虚方法的区别实际上好像并没有什么卵用(* ̄︶ ̄)y……

 

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

  • [精粹]正则表达式30分钟入门教程(转)

    [精华]正则表达式30分钟入门教程(转) 前言   今天做东西的时候碰到个正则表达式的需求,以前做数据验证的时候因为都是一些通用的东...

  • WCF学习1

    WCF学习一 在阅读博客园 WCF开发实战系列一:创建第一个WCF服务 一文中,发现手动配置App.config还是有难度。这篇文章没讲很多...

  • .NET 类库研究必备参照 添加微软企业库源码

    .NET 类库研究必备参考 添加微软企业库源码 前不久,为大家提供了一个.NET 类库参考源码的网站,扣丁格鲁(谐音&ldquo;coding guru...

  • .NET 类库研究必备参照 扣丁格鲁

    .NET 类库研究必备参考 扣丁格鲁 .NET 类库的强大让我们很轻松的解决常见问题,作为一个好专研的程序员,为了更上一层楼,研究CLR...

  • 垃圾回收机制GC知识再总结兼谈怎么用好GC

    垃圾回收机制GC知识再总结兼谈如何用好GC 一、为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1、为对应的资源分配内...

  • .NET 4.5.1 参照源码索引

    .NET 4.5.1 参考源码索引...

  • 关于GC跟析构函数的一个趣题

    关于GC和析构函数的一个趣题 这个有趣的问题感谢装配脑袋友情提供。 请看如下代码: public class Dummy { publi...

  • 对程序集的几点懂得

    对程序集的几点理解   CLR对程序集的解释是:程序集是一个或多个类型定义文件及资源文件的集合。平时我们常见的后缀为dll或exe的...

  • 渣滓回收期算法简介

    垃圾回收期算法简介 垃圾回收器检查托管堆中是否有应用程序不再使用的对象,如果有,他们使用的内存就可以回收(如果一次垃圾回收之后...

  • CLR值类型跟引用类型

    CLR值类型和引用类型 知识点:引用类型、值类型、装箱、拆箱 CLR支持两种类型:引用类型和值类型。引用类型在堆上分配内存,值类型在线...