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利用元数据提取这些类型相关的信息,创建一个数据结构描述类型本身,称作类型对象,其后定义的对象,对象的类型对象指针指向相应的类型对象。