CLR Via C# 第四章 类型基础——读书笔记
2016-05-19 14:58
615 查看
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; a3b3 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方法中获得的就是返回对象的类型对象的指针
相关文章推荐
- c#Lambda
- C# 扫雷
- C#的百度地图开发 IP定位
- C#如何操控FTP
- 堆栈和托管堆 c#(1)
- C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
- 【C#】新建服务自动发送邮件
- C#动态调用webservice的方法
- C#中如果正确使用线程Task类和Thread类
- c#获取系统语言及版本信息
- c# 基本值类型
- 关于c#短信发送接口使用说明
- C# Math.Round函数
- C# 开发者最经常犯的 8 个错误
- C#通过COM组件调用C++的代码(转载)
- C#判断一个string是否为数字
- c#xml追加读取节点
- C#和.NET 2.0实战(2016-3-18 15:17、2016-4-21 10:08)
- C#程序集引入无效的解决方法
- [转]C# 理解lock