继承和多态在C#中的实现

刚开始写blog,最近要考试就先把以前写的一些读书心得和经验总结记下,当然难免有错,欢迎大家指正。

与调用普通方法不同,当CLR遇到vitual 方法的时候,会使用callvirt (IL)命令与普通的call(IL)不同callvirt除了第一句外(把this送到ecx寄存器),还有第二句,把this对象的type handle送到了eax寄存器中。另外callvirt还会先检查this对象是否为null
call
mov ecx, esi
call dword ptr ds:[352108h]

callvirt
move ecx, esi
move eax, dword ptr [ecx]
call dword ptr [eax + 38h]

其中最关键的就是那个offset, 对于每个virtual方法,有以下的属性 

  继承和多态在C#中的实现


这张图是各个关键字所对应的属性 
         继承和多态在C#中的实现
 

如果新方法具有newslot的属性(比如使用了virtual关键字),那么新方法的offset就会至少在原类型的virtual method 的offest最大值上+1,如果不是newslot那么就会在base类型的virtual method table中找到与该方法同名的方法,并重用原类型的那个virtual method offset。如果找不到,就会新建一个。简而言之就是有则使用原来的offset,没有就扩大virtual method table,使用新增的offset。这样在不同类型中同样的方法在VMT中的offset是相同的,不同的是this指针的地址也就是eax中的内容,这样就保证了第三句call dword ptr [eax + 38h] 的执行会调用到正确的方法,多态也就得到了实现。

 

注意从上图可以看出override的方法也是vitual method,只不过它的newslot0,说明不需要为它寻找新的空间。



以上是当时看Essential。NET记的体会。很简陋。希望能看出点东西。

 

 

 

你可能感兴趣的:(继承)