您的位置:首页 > 编程语言 > C#

带着问题读CLR via C#(二)类型基础

2013-04-01 23:04 489 查看
Q1: Object类型包含哪些方法?

A1: Object类型共包含6个方法,Equals, GetHashCode, ToString, GetType, MemberwiseClone和Finalize.

Q2: new一个对象的过程是什么?

A2: 1)计算对象所需字节数,包括该类型及其基类型定义的所有实例字段所需的字节数和类型对象指针、同步块索引所需字节数,类型指针和同步块索引是CLR用来管理对象的;2)在托管堆上分配该对象所需内存空间;3)初始化类型对象指针和同步块索引;4)执行构造函数。大多数编译器都在构造函数中自动生成一段代码调用基类构造函数,每个类型的构造函数在执行时都会初始化该类型定义的实例字段。5)返回指向新建对象的一个引用,保存在对象变量中。

可用如下代码验证第四步:

View Code

namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
Employee e;
Int32 year;
e = new Employee();
e = Employee.Lookup("Joe");
year = e.GetYearsEmployed();
e.GenProgressReport();
}
}

class Employee
{
// 实例方法
public Int32 GetYearsEmployed()
{
//...
}
// 虚方法
public virtual string GenProgressReport()
{
//...
}
// 静态方法
public static Employee Lookup(string name)
{
//...
}
}

class Manager : Employee
{
// 对父方法重写
public override string GenProgressReport()
{
//...
}
}
}


A7:

1)CLR检查该方法内部引用的所有类型(Employee, Int32, Manager, String),确保定义了这些类型的程序集已成功加载;

2)CLR利用程序集的元数据提取这些类型的相关信息,并创建一些数据结构来表示类型本身,如下图所示:



3)执行"序幕代码",在线程栈中为局部变量分配内存,并初始化它们,如下图所示:



4)构建Manager对象,在托管堆中创建一个Manager类型的实例,CLR会初始化该实例的类型对象指针,让它引用与实例对应的类型对象,本例中为Manager类型对象;此外CLR会初始化同步块索引,并将该实例所有实例字段设为null或0,再调用构造函数,new操作符会返回该实例内存地址,该地址保存在e中,如下图:



5)Lookup是一个静态方法,调用时CLR会定位定义该静态方法的类型对应的类型对象,然后JIT编译器在该类型对象的方法表中查找被调用的方法的记录项,对方法进行JIT编译(第一次执行),执行编译后的代码。本例中,假定查出的实例是一个i额Manager类型,则在堆中创建一个Manager实例,用查出的信息初始化该实例,并返回它的地址储存在e中,此时,第一个初始化的Manger对象将没有指针指向它,它成为垃圾回收对象。见下图:



6)GetYearsLookup是一个非虚实例方法,在调用时,JIT编译器会找到发出调用的标量(e)的类型对应的类型对象,本例中为Employee类型对象,因为e被定义为了Employee类型。如果Employee中没有定义该方法,则会继续向上一层查找,知道查找到Object类型对象,查找到该方法后,JIT编译器对其进行编译(第一次执行),再执行变异后的代码,将执行结果保存在局部变量中。见下图:



7)GetProgressReport为定义在Employee中的虚方法,调用一个虚方法,JIT编译器会在方法中生成一些额外代码,这些代码在每次调用方法时都会执行。它首先会检测发出调用的变量,根据地址查找到发出调用的实例,本例为一个Manager对象,然后检测对象内部的类型指针,找到该对象的实际类型,从实际类型对象的方法列表中查找调用的方法的记录项,进行JIT编译(第一次执行),执行变异后代码。见下图:



Q8: 如何理解类型对象?

A8: 类型对象本质上也是对象,它也包含类型对象指针成员,CLR创建这些类型对象时,也会对其进行初始化。CLR开始在一个进程中运行时,会立即为MSCorLib.dll中定义的System.Type对象创建一个特殊的类型对象,Q7中的Emloyee和Manager都是Type类型的“实例”,它们的类型对象指针都会指向Type类型对象,而Type类型对象的类型对象指针则会指向自己。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: