1 所有类型都从System.Object派生
2 类型转换
3 定名空间和措施集
4 运行时的彼此关系
本章讲述使用类型和CLR时需掌握的根本常识。具体地说,要讨论所有类型都具有的一组根基行为。
讨论类型安适性、定名空间、措施集、以及如何将东西从一种类型转换成另一种类型。
本章最后会解释类型、东西、线程栈和托管堆在运行时的彼此关系。
4.1 所有类型都从System.Object派生
CLR要求每个类型最终都从System.Object类型派生。从而确保类每个东西都具备一组最根基的要领。
[果然要领]
Equals
GetHashCode
ToString
GetType
[受掩护要领]
MemberwiseClone
Finalize
CLR要求所有东西都用new操纵符创建。
以下new操纵符所做的工作:
1 计算类型及其所有基类型(一直到System.Object,虽然它没有界说本身的实例字段)中界说的所有实例字段需要的字节数。堆上每个东西都需要一些特别的成员,包孕“类型东西指针”和“同步块索引”。CLR操作这些成员打点东西。特别成员的字节数要计入东西巨细。
2 从托管堆中分配类型要求的字节数,从而分配东西的内存,分配的所有字节都设为0。
3 初始化东西的“类型东西指针”和“同步块索引”成员。
4 挪用类型的实例结构器,通报在new挪用中指定的实参。大大都编译器都在结构器中自动生成代码来挪用基类结构器。每个类型的结构器都卖力初始化该类型界说的实例字段。最终挪用System.Object的结构器,该结构器什么都不做,简单地返回。
new执行了所有这些操纵之后,返回指向新建东西的一个引用(或指针)。
并且没有和new操纵符对应的delete操纵符;换言之,没有步伐显式释放为东西分配的内存。CLR给与了垃圾回收机制,自动检测一个东西不再被使用或是访谒,并自动释放该东西的内存。
4.2 类型转换
CLR最重要的特性之一就是类型安适。在运行时,CLR总是知道东西的类型是什么。挪用GetType要领即可。
CLR允许将东西转换为它的(实际)类型或者它的任何基类型。
C#不要求任何特殊语法即可讲东西转换为它的任何基类型,因为向基类型的转换被认为是一种安适的隐式转换;然而,将东西转换为它的某个派生类型时,C#要求开发人员只能进行显式转换,因为这种转换可能在运行时掉败。
使用C#的is和as操纵符来转型
is查抄东西是否兼容于指定类型,返回Boolean值,is操纵符永远不抛出异常;
CLR的类型查抄增强了安适性,但无疑会对性能造成必然影响。这是因为CLR首先必需判断变量引用的东西的实际类型,然后,CLR必需遍历担任条理布局,用每个基类型去查对指定的类型。
由于这是一个相当常用的编程模式,所以C#专门供给了as操纵符,目的是简化这种代码的写法,同时提升性能。CLR核实一个东西是否兼容与一种类型,如果是,as返回同一个东西的非null引用,如果不兼容,as返回null。注意:as操纵符只校验一次东西类型。
C#允许类型界说转换操纵符要领,详情参见8.5节 “转换操纵符要领”。
4.3 定名空间和措施集
定名空间 对相关的类型进行逻辑分组,开发人员可以通过定名空间便利定位类型。
对付编译器,定名空间的感化就是为类型名称附件以句号支解的标记,使名称变得更长,更可能具有独一性。
CLR对“定名空间”一无所知。
C# using指令的另一种形式允许为类型或定名空间创建别号。
定名空间和措施集的关系
注意,定名空间和措施集(实现类型的文件)不必然相关。出格是,同一个名空间中的类型可能在差别措施集中实现,同一个措施集也可能包罗差别定名空间中的类型。
在文档中查找类型时,文档会明确指出类型所属的定名空间,以及实现了该类型的措施集。
4.4 运行时的彼此关系
本节将解释类型、东西、线程栈和托管堆在运行时的彼此关系。
别的,还将解释挪用静态要领、实例要领和虚要领的区别。
“序幕”(prologue)代码:在要领开始做事情前对其进行初始化;
“尾声”(epilogue)代码:在要领做完事情后对其进行清理,以便返回至挪用者。
堆上所有东西都包罗两个特别成员:类型东西指针 和 同步块索引。
东西含有一个指针指向东西的类型东西(类型东西中包罗静态字段表和要领表)。
CLR创建类型东西时,必需初始化这些成员。CLR开始在一个进程中运行时,会当即为MSCorLib.dll中界说的System.Type类型创建一个特殊的类型东西。Employee和Manager类型东西都是该类型的“实例”。因此,它们的类型东西指针成员会初始化成对System.Type类型东西的引用。固然,System.Type类型东西自己也是东西,,内部也有“类型东西指针”成员。这个指针指向它自己,因为System.Type类型东西自己是一个类型东西的“实例”。这就是CLR的整个类型系统及其事情方法。也就是说,GetType要领返回指向东西的类型东西的指针,这样就可以判断系统中的任何东西的真实类型了。