观 CLR-via-C# 总结之--第四章:类型基础

类型基础

4.1所有类型都从System.Object中派生。

  1. System.Object类中的公共实例方法有:Equals(如果两个对象具有相同的值,就返回true);GetHashCode(返回对象的值的一个哈希码,如果某个类型的对象要在一个哈希表集合中作为key使用,应该重写这个方法。方法应该为不同的对象提供一个良好的分布(是指针对所有的输入,GetHashCode生成的哈希值应该在所有整数中产生一个随机分布)。);Tostring(默认返回类型为this.GetType().FullName().我们 通常需要对此方法进行重写。)GetType(返回从Type派生的一个对象实例,指出调用对象是什么类型,返回的Type对象可以配合反射,获取与对象类型有关的元数据信息。)其中派生类也可访问受保护的方法:MemberwiseClose(能创建类型的一个新实例,并将新对象的实例字段设与this对象的实例字段一致,返回的是对新实例的一个引用。)Finalize(在垃圾回收器判断对象应该被作为垃圾收集之后,在对象内存被回收之前,会调用这个虚方法,需要在回收之前执行一些清理工作的类型需要重写这个方法。)(既然Object是所以方法的基类,那么为什么其方法还分为公共方法和保护方法?)
  2. New操作符所做的事情有:它计算类型,及其所有基类型中定义的所有实例字段需要的字节数(为什么要计算基类?)。堆上的所有对象都需要一些额外的成员,并对其进行初始化---“类型对象指针(指向类在堆中分配的地址)”和同步块索引(为了支持线程同步的功能,折中的去掉原有的为每个对象都分配同步块而采取折中的办法:只为每个对象分配同步块索引,CLR在加载时会新建一个同步块数组,当某些对象需要同步时,CLR会为其分配一个同步块,并且把该同步块在数组的索引加入到对象的同步块索引中)用于CLR管理对象。这些额外成员的字节数会计入对象大小。它从托管堆中分配指定类型要求的字节数,从而分配对象的内存,分配的所有字节都设置为0;调用类型的实例构造器,向其传入在对new的调用中指定的任何参数。大多数编译器都在构造器中自动生成代码来调用一个基类构造器。每个类型的构造器在调用时,都要负责初始化由这个类型定义的实例字段。

3.new执行了所有操作之后,会返回指向新建对象一个引用。

 

4.2类型转换

  1. CLR允许将一个对象转化为它的实际对象或者它的任何基类型,这是一种安全的隐式转换。也允许显式向其派生类转换。
  2. Is(检查一个对象是否兼容于指定的类型,不会抛出异常)和as(如果不兼容类型会返回null)操作符来转型。

 

4.3命名空间

  1. 命名空间是由编译器而成的,CLR不知道命名空间的事情,只知道类型的完整名称。
  2. 编译器调用确实存在的方法,向这些方法传递正确数量的实参,保证实参有正确的类型,正确使用方法的返回值。如果在源代码和应用的程序集都找不到,就会在类型前附加System.Io./System.Text.前缀进行匹配。
  3. 在默认情况下,编译器会自动在MSCorLib程序集(包含了所有Framework类库类型的定义如:Object,Int,String)中查找”引用类型”。
  4. 允许设置别名如:using C=A.B形式。

 

4.4运行时的相互联系

  1. 一个线程创建时,会分配一个1M大小的栈,用于向方法传递实参,并用于方法内部定义的局部变量。栈是从高位内存地址向低位内存地址构建的
  2. 在一个最基本的方法中,应包含一些”序幕”代码,负责方法在开始工作前 对其进行初始化。还应包含一些”尾声”代码,负责方法完成工作之后对其进行清理,然后才返回调用者。
  3. 栈帧(:代表的是当前线程的调用栈中的一个方法调用,在执行线程的过程中进行的每个方法调用都会在调用栈中创建并压入一个栈帧。)展开
  4. 当JIT编译器将调用类的IL代码转换成CPU指令时,会注意到调用类内部引用的的所有类型(应该是通过加载元数据,本人看法)。在这个时候,CLR要确保定义了这些类型的使用程序集都加载。然后,利用程序集的元数据,CLR提取与这些类型有关的信息,并创建一些数据结构来表示类型本身。
  5. 类型对象在托管堆中的组成:类对象指针,同步块索引,静态字段,方法表(类型中定义的每个方法都有一个记录项)。其中类型对象和类对象不是一个东西,类对象包括:类对象指针,同步块索引,同类型或者基类型定义的实例字段。
  6. CLR会自动将所有的局部变量初始化为NULL或者0,然而,如果试图从一个尚未显示初始化的局部变量读取数据,会报”未赋值的局部变量”错误。
  7. 任何时候在堆上新建一个对象,CLR都会自动初始化内部类型对象指针成员,让它引用与对象对应的类型对象。此外,CLR会先初始化同步块索引,并将对象的所有实例字段设为null或0,再调用类型的构造器,new操作符会返回对象的内存地址。
  8. 调用一个静态方法时,CLR会定位与定义静态方法的类型对应的类型对象。然后,JIT从类型对象的方法表中查找与被调用的方法对应的记录项。调用非虚实例方法时,JIT编译器会找到与”发出调用的那个变量的类型”对应的类型对象,
  9. 在对象调用之前,CLR都会对其进行初始化,CLR开始在一个进程中运行时,会立即为MSCroLib.dll定义的System.Type类型创建一个特殊的类型对象,其他类型对象都是其实例。类型对象的本质也是对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值