星空网 > 软件开发 > ASP.net

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

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

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

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

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

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

 

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

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

接下来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()内部的引用类型,创建两个类型对象

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

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

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

1,调用静态方法:

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

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

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

 

3,虚实例方法:

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

总结:

  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……

 




原标题:CLR调用静态方法、实例方法和虚方法的区别

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

100%成功注册谷歌邮箱Gmail的方式, 真香!:https://www.kjdsnews.com/a/776441.html
货物出口退税率为0,出口都会被视同内销处理吗?:https://www.kjdsnews.com/a/776442.html
完了,芭比Q了~设错促销导致0元卖货,血亏!亚马逊促销工具要用对!:https://www.kjdsnews.com/a/776443.html
如何做出高端A+页面的新品牌故事板块:https://www.kjdsnews.com/a/776444.html
Best Buy官网网址,Best Buy是什么平台?:https://www.kjdsnews.com/a/776445.html
2022春节亚马逊备货的tips!你掌握了吗?:https://www.kjdsnews.com/a/776446.html
TikTok 将推出先买后付服务 :https://www.goluckyvip.com/news/188219.html
深圳有没有比较好玩的景点 深圳有没有比较好玩的景点推荐一下:https://www.vstour.cn/a/366175.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流