【CLR-sos调试】关于方法表继承调用问题的总结
2011-11-10 11:18
337 查看
CLR调用方法的机制到底是什么样子的?子类方法表的构成?这篇文章以我的实际经历加以总结,给出问题的答案。
首先,问题的引入,如下:
输出是什么呢?如果你是大牛,对这个问题很明了,那么你没有必要往下看了,到这里请停住,以免浪费了您的宝贵时间,我会觉的惭愧的。 - -。如果你对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。
首先,问题的引入,如下:
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。
相关文章推荐
- 关于子类继承父类后调用方法的问题
- 最近在ArcGIS Engine开发中关于调用gp工具过程出现COM 组件的调用返回了错误 HRESULT E_FAIL 错误的解决方法 和 学习oracle中遇到的一些问题总结
- c# 关于基类和子类的方法调用问题--总结
- 关于子类继承父类后调用方法的问题
- 继承中关于调用构造方法的问题
- 关于NSXMLParser的foundCharacters方法调用次数的问题
- 关于html+ashx开发中几个问题的解决方法的感想和总结
- 关于方法重载和方法覆盖的实际调用问题
- 关于类继承中子类方法比父类方法丰富,一个引用值传递的小问题
- Atitit. 构造ast 语法树的总结attilax oao 1. Ast结构树形12. ast view (自是个160k的jar )22.1. 多条语句ast结构22.2. 变量定义 int b,c; 的ast结构22.3. 方法调用meth1(a=1,b=2,c=3); 的ast结构23. 误解的问题33.1. 语法书子能是个二叉树,实际上多叉树越好..33.2. 非要不个ast放到个s
- java继承时候关于父类中的静态方法的问题
- 继承中关于基类私有方法的问题
- 关于Android生命周期方法调用return的问题
- Java【多线程知识总结(7)】多线程同步问题-关于synchronized代码块和synchronized方法的应用
- 关于混淆打包后,webview 无法调用js方法 的问题
- [拦截器]关于拦截方法调用其他内部方法无法被拦截问题的解决
- 关于多态性的动态绑定问题, 对象调用方法的执行过程.
- 关于C++中菱形继承和虚继承的问题总结
- 关于调用Dialog的复写的show()方法出现空指针的问题
- 理解和掌握类的加载过程以及子类继承父类后,重写方法的调用问题