CLR Via C# 第四章 类型基础——读书笔记

1.类型转换


在以下示例代码中,第一部分能通过编译,因为方法PromoteEmoloyee期待一个Object,而Manage正是Object一个派生类,所以能进入该方法,
进入方法后,o是Manager对象的引用, 由于对o向Employee转型,CLR核实对象o引用的是一个Emoloyee或是其派生类对象,核实成功,CLR执行转型。

而第二部分,同理,DateTime能够进入方法, 但是,CLR检查类型转换时发现o的引用既不是Employee,也不是其派生类型,此时CLR会禁止转型,抛出 System.InvalidCastException异常

这个示例体现了CLR的类型安全,

特别地,此程序可以在方法的参数中将类型改为Employee(基类),从而使得程序在编译时就发现错误。

public static void Main2() {
      // Construct a Manager object and pass it to PromoteEmployee.
      // A Manager IS-A Object: PromoteEmployee runs OK.
      Manager m = new Manager();//第一部分
      PromoteEmployee(m);

      // Construct a DateTime object and pass it to PromoteEmployee.
      // A DateTime is NOT derived from Employee. PromoteEmployee 
      // throws a System.InvalidCastException exception. 
      DateTime newYears = new DateTime(2007, 1, 1);//第二部分
      PromoteEmployee(newYears);
   }

 public static void PromoteEmployee(Object o) {
      // At this point, the compiler doesn't know exactly what
      // type of object o refers to. So the compiler allows the 
      // code to compile. However, at run time, the CLR does know 
      // what type o refers to (each time the cast is performed) and
      // it checks whether the object抯 type is Employee or any type
      // that is derived from Employee.
      Employee e = (Employee) o;
   }

2.借助C#得 is,as 操作符来转型

以下示例程序中,这是常用的写法,
但是,
if (o is Employee) {
         Employee e = (Employee)o;
         // Use e within the remainder of the 'if' statement. 
      }
在这种写法中,is操作符核实o是否兼容于Employee类型,如果是,则进入if语句内,CLR再次核实o是否引用一个Employee,
可见对性能造成一定影响。

所以提供as操作符,此操作符核实o是否兼容于Employee类型,若是则返回同一对象的非null引用,否则返回null
Employee e = o as Employee;
      if (e != null) {
         // Use e within the 'if' statement.
      }

3.类型,对象,线程栈和托管堆在运行时的相互关系

所有堆上的对象都包含两个额外成员: 类型对象指针和同步块索引
类型对象:方法初始化时CLR利用元数据提取这些类型相关的信息,创建一个数据结构描述类型本身,称作类型对象,其后定义的对象,对象的类型对象指针指向相应的类型对象。


a.调用Employee的静态方法Lookup,CLR定位于定义静态方法的类型对应的类型对象,JIT编译器在类型对象的方法表中查找被调用方法对应的记录项,进行JIT编译(如需要),再调用JIT编译好的代码。




b.调用非虚实例方法,JIT编译器找到调用的那个变量(e)的类型(Employee),如果该类型中没那个方法,则回溯类层次结构(直到object)查找方法。




c.调用虚实例方法(多态),JIT编译器找到发出调用的实际对象,发现是一个Manage对象(上一步初始化了一个Manage对象并将地址保存到e),跟随其中类型对象指针找到该实际类型,在类型对象方法表中找到该方法的记录项,进行JIT编译(如需要)。



注:类型对象本质也是对象,CLR在创建类型对象时,会使用System.Type类创建一些特殊类型对象,Employee,Manager类型对象都是Type类型的“实例”
特别地,而Type类型对象本身也是类型,内部的类型对象指针则指向本身。
System.object 中的GetType方法中获得的就是返回对象的类型对象的指针

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值