CLR怎样实现虚方法的多态调用(2)

在上一篇文章CLR怎样实现虚方法的多态调用(1)中主要介绍了CLR怎样多态调用虚方法以及各种类型 的方法在Method Table中的排布,但是没有介绍怎样调用接口方法,当某个对象向上转型为接口时进行多 态调用时,CLR是怎样实现的呢?以下面这段代码为例来说明:

namespace Demo
{
   public interface IFoo
   {
     void Foo();
   }

   public class Base : IFoo
   {
     public void Foo()
     {
       Console.WriteLine("In base's Foo function");
     }
   }

   class Program
   {
     static void Main(string[] args)
     {
       IFoo i = new Base();
       i.Foo();
     }
   }
}

在Essential .NET中,Don Box向读者简单描述了基于接口的多态调用,在堆中有一个全局接口映射表 ,当某个类实现了一个接口,就会在这个接口表中增加项,而增加的这些项又指向这个具体类的Method Table中的Method,可能说的不是太清楚,就用个图来表示:

时间: 2024-09-01 13:25:43

CLR怎样实现虚方法的多态调用(2)的相关文章

CLR怎样实现虚方法的多态调用(1)

最近一直对.net framework中,虚方法的调用是如何实现这个问题有些疑惑,在看了Essential .Net 关于Method的那一章和Artech推荐的文章Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects以后,还是一知半解,有些疑惑得不到答案.主要有这些: 父类定义的非虚方法是否在子类中有拷贝? 虚方法是如何实现多态的? 子类继承父类的虚方法实现是否和继承非虚方法机制相同? 如果

C#类中虚方法相互调用的潜在重载错误

错误    当我们编写基类虚方法时,需要注意一个问题,就是基类中虚方法的相互调用,有可能引起派生类重载时的潜在错误隐患.当然这个错误并不是C#语言设计的缺陷,而是一个不可避免的实现而已.当然如果我们是要编写通用的组建基类,就需要注意一下了.     或许我们刚开始做OOP的时候,对于有没有方法有没有virtual根本不在乎,很多是时候我们都重写了(rewrite)了基类方法.当然在需要确定重载(override)的时候,virtual关键字限定基类方法是不可少的.那么是不时我们就可以把基类的方法

艾伟:C#类和接口、虚方法和抽象方法及值类型和引用类型的区别

1.C#类和接口的区别 接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念! 而类是负责功能的具体实现! 在类中也有抽象类的定义,抽象类与接口的区别在于: 抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进一步的专业化. 但接口是一个行为的规范,里面的所有东西都是抽象的! 一个类只可以继承一个基类也就是父类,但可以实现多个接口 PS: 接口除了规范一个行为之外,在具体项目中的实际作用也是十分重要的,在面向对象的设计原则以及设计模式的使用中,无不体

用WinDbg探索CLR世界 [3] 跟踪方法的 JIT 过程

过程 本来想按照 sos 的帮助文件上命令的分类逐步介绍 WinDbg 下使用 sos 调试 CLR 程序,但发现这样实在不够直观.索性改成根据我分析 CLR 的实际案例,step by step 介绍功能,这样结构上虽然混乱一点,但更加直观,也易于上手 :P 前面两篇文章里面分别介绍了 WinDbg 的调试配置和线程的基本概念,这篇文章将针对 JIT 编译对象方法的流程进行分析,逐步介绍如何使用 WinDbg 调试 CLR 程序. 用WinDbg探索CLR世界 [1] - 安装与环境配置用Wi

虚方法重写

1.实例解析 控制台程序 class Program { static void Main(string[] args) { DerivedType derivedInstance = new DerivedType(); string line; while ((line = Console.ReadLine()) != null) { Console.WriteLine("----"); } } } public class BadlyConstructedType { prote

在派生类中对虚方法进行重载

先让我们回顾一下普通的方法重载.普通的方法重载指的是:类中两个以上的方法(包括隐藏的继承而来的方法),取的名字相同,只要使用的参数类型或者参数个数不同,编译器便知道在何种情况下应该调用哪个方法. 而对基类虚方法的重载是函数重载的另一种特殊形式.在派生类中重新定义此虚函数时,要求的是方法名称.返回值类型.参数表中的参数个数.类型.顺序都必须与基类中的虚函数完全一致.在派生类中声明对虚方法的重载,要求在声明中加上override关键字,而且不能有new,static或virtual修饰符. 还是让我

C#的虚方法

当类中的方法声明前加上了virtual修饰符,我们称之为虚方法,反之为非虚.使用了virtual修饰符后,不允许再有static,abstract,或override修饰符. 对于非虚的方法,无论被其所在类的实例调用,还是被这个类的派生类的实例调用,方法的执行方式不变.而对于虚方法,它的执行方式可以被派生类改变,这种改变是通过方法的重载来实现的. 下面的例子说明了虚方法与非虚方法的区别. 程序清单14-3: using System; class A { public void F(){Cons

super-为什么子类重写父类方法之后还要调用父类同名方法

问题描述 为什么子类重写父类方法之后还要调用父类同名方法 为什么子类重写父类方法之后还要调用父类同名方法 比如public class A extends B { public void say ( ) { super.say ( ); } 为什么重写父类方法之后还要在方法体里面用super关键词调用父类的同名方法呢 解决方案 你可以不调用,这个你自定,不是必须 解决方案二: SubClasing用法--子类重写父类方法,父类直接调用实现方式子类调用父类方法子类调用父类方法 解决方案三: 我想到

[CLR via C#]8. 方法

原文:[CLR via C#]8. 方法 一.实例构造器和类(引用类型) 类实例构造器是允许将类型的实例初始化为良好状态的一种特殊的方法. 类实例构造器方法在"方法定义元数据表"中始终叫.ctor(代表constructor).创建一个引用类型的实例时,首先为实例的数据字段分配内存,然后初始化对象的附加字段(类型对象指针和同步块索引),最后调用类型的实例构造器来设置对象的初始化状态. 构造引用类型的对象时,在调用类型的实例构造器之前,为对象分配的内存总是先被归零.构造器将没有显式重写的