zoukankan      html  css  js  c++  java
  • 【CLRsos调试】关于方法表继承调用问题的总结

    CLR调用方法的机制到底是什么样子的?子类方法表的构成?这篇文章以我的实际经历加以总结,给出问题的答案。

    首先,问题的引入,如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace 方法表构成CLR调用测试
    {
    public class Father
    {
    public void DoWork()
    {
    Console.WriteLine("Father.DoWork()");
    }
    public virtual void DoVirtualWork()
    {
    Console.WriteLine("Father.DoVirtualWork()");
    }
    public virtual void DoVirtualWork2()
    {
    Console.WriteLine("Father.DoVirtualWork2()");
    }
    }
    public class Son : Father
    {
    public new void DoWork()
    {
    Console.WriteLine("Son.DoWork()");
    }
    public override void DoVirtualWork()
    {
    Console.WriteLine("Son.DoVirtualWork()");
    }
    public new void DoVirtualWork2()
    {
    Console.WriteLine("Son.DoVirtualWork2()");
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    //下面的输出是什么
    Father son2 = new Son();
    son2.DoWork();
    son2.DoVirtualWork();
    son2.DoVirtualWork2();
    }
    }
    }

    输出是什么呢?如果你是大牛,对这个问题很明了,那么你没有必要往下看了,到这里请停住,以免浪费了您的宝贵时间,我会觉的惭愧的。 - -。如果你对CLR,IL,SOS调试等一无所知,那么您也大可以抽出您的宝贵时间看点别的,- -!。博友心声:废话一大堆,赶快进入正题!DebugLZQ:马上!

    让我们先看下问题的输出:

     咦,这个结果!!!!!

    可能,你认为DebugLZQ的这篇文章,完全是无理取闹,你没事搞这玩意做甚?这里提醒各位,这里要谈论的话题可是深入理解面相对象的三大支柱不可或缺的啊,至少我们使用的.NET Framework类库,无处不存在着继承,重写,覆盖。。。

    之前,对CLR有过相关的研究,下面直接给出问题的正确答案!(DebugLZQ的错误认识就不与各位博友分享了,以免误导各位,适得其反。)

    从CLR调用的机制着手解答:

    首先每个类型(Father、Son)都有自己的方法表,CLR在调用一个方法时,已经知道这个方法是不是虚方法。如果不是虚方法,那么就去检查变量类型的method table,因此son2.DoWork()查找的是Father的MT(如果找不到那么会去基类里找),找到了就执行它(或者先JIT再执行)。如果是虚方法,那么会根据引用找到堆上的那个对象,根据对象的type pointer找到对象的真正类型(即GetType方法的返回类型),因此son2.DoVirtualWork()会直接查找Son的MT(如果找不到那么就去基类,这跟非虚方法是相同的)。

    关于子类方法表构成:包含父类的虚方法,不包含父类的实例方法。

    关于SOS调试:请参考msdn的总结:http://msdn.microsoft.com/zh-cn/library/bb190764.aspx



  • 相关阅读:
    CCF-CSP201512-3 画图
    CCF-CSP201512-2 消除类游戏
    CCF-CSP201606-4 游戏(BFS)
    CCF-CSP201604-2 俄罗斯方块
    HDU1035 Robot Motion(dfs)
    Java Srting之Calendar日历类(五)——Calendar中计算时间的方法add()
    java如何获取当前日期和时间
    double 类型怎样不用科学计数法表示并且使用Java正则表达式去掉Double类型的数据后面多余的0
    @SpringBootApplication(exclude={DataSourceAutoConfiguration.class})注解作用
    java.util.Date.toString()方法实例
  • 原文地址:https://www.cnblogs.com/DebugLZQ/p/2244226.html
Copyright © 2011-2022 走看看