1 类型系统
对CLR进行的所有活动都是以类型为基础的,类型为应用程序和组件提供了所需的功能,类型也提供了一种机制可以让一种语言编写的代码和另一种语言编写的代码进行无缝的集成,从某种意义上说,CLR是对CTS的一种实现。
1)通用类型系统
微软制定了一种叫CTS规范,它规定了所有面向CLR的语言应该遵守的集合。它规定了一个类型可以包含0个或多个成员,在类型中其实就只有两种成员:字段和方法,像属性、事件等都是针对某种语言对这两种成员的简写方式,在编译后这些会由编译器转换成对应的字段或方法,这些可以通过反汇编工具进行查看。同时CTS还规定了类型的可见性以及访问这些类型成员的可见性规则等等,总之,无论我们使用哪种语言编写面向CLR的程序集,这种语言必须符合CTS规范。
2) 所有类型的基类Object
CLR要求每个类型都直接或间接的继承自object,在编写我们的类型时如果没有显示的定义我们的继承类型,系统会默认继承自object,这就保证了任何对象都有一组方法的最小集合,object包含如下的方法:Equals、GetHashCode、ToString、GetType、MemberwiseClone和Finalize。
CLR要求所有的对象都要用new操作符来创建,object o = new object(); 在这个看似简单的语句后面CLR为我们做了如下的工作:
a) 从托管堆中分配指定类型所需数量的字节来作为存储其对象的内存空间。
b) 初始化对象的附加成员。每个对象实例都有两个附加成员,用于管理对象的实例,一个是指向类型方法表的指针;一个是SyncBlockIndex,进行线程同步控制。
c) 调用类型的实例构造器。
在new完成上面的操作后,返回一个指向新创建对象的引用,保存在o中。
2 引用类型和值类型
CLR支持两种类型:值类型和引用类型。
1) 值类型
值类型是我们最常用到的类型,它是一种轻量级类型,速度快,效率高,值类型总是分配在它声明的地方(值类型作为临时变量直接分配在线程的堆栈上,作为引用类型的成员时会分配在托管堆上),在作用域结束后自动释放(作为引用类型的成员时会和类型一起由垃圾收集器释放)。值类型包括基元类型(int,char、float等)、枚举类型、结构体类型,它们都是从ValueType类型继承而来,而ValueType又是从object直接继承而来,值类型也就具有了object的一组最小方法集,只是值类型重写了一些方法以符合值类型的计算要求。
2)引用类型
引用类型直接或间接的继承自object,它包括自描述类型、指针类型、接口类型、委托类型,这些类型都需要用关键字new来创建,它们被分配在托管堆上,object reference = new object(); reference作为对象的引用,在对象创建完成后保留了指向刚创建的对象的空间地址,reference本身会存放在线程的堆栈上。
3)两者区别
a) 存储位置不同:值类型部署在栈上,引用类型部署在托管堆上。
b) 类型继承:引用类型可以派生出新的类型,而值类型不能。
c) 赋值方式:引用类型变量的赋值只复制对对象的引用,而不复制对象本身;而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。
d) null:引用类型可以为null,正常情况下值类型不能被分配null值(可空类型功能允许将 null 赋给值类型,如 int? valueNull = null;)。