GJM : 通用类型系统(Common Type System CTS)
C#指南笔记。
一、CTS定义了一个类型库,无论时Visual Basic.NET还是c#,他们的类型系统大体类似。因此.NET将各种不同的编程语言的数据类型进行抽象,就有了CTS。虽然每种编程语言都有自己的类型系统,但编译后都会转成CTS类型。不同的语言编写的程序直间可以相互操作。Vb的integer而C#的System.Int32都对应CTS的System.Int32类型。
CTS类型主要分成两大类:引用类型和值类型,这两个类型可以相互转换,方法是装箱和拆箱。
有图的可知,引用类型直接继承自Object对象,值类型继承自ValueType对象,而ValueType继承自Object对象。所以CTS类型最终继承自Object。
二、 值类型和引用类型。
值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在堆中。
对于引用类型而言,由于数据存储在堆中,指向它的引用不止一个,因此当其它引用对数据进行修改时会影响到别的引用。
在托管代码中,每种类型有两种分配内存的方式,分配在托管栈中,分配在托管堆中。
二者的区别:
1. 分配在托管栈中的变量会在创建它们的方法返回时自动释放。
char userInput= 'c';
在一个方法内声明Char类型的变量userInput它的值为‘c’当实例化它的方法结束时,userInput变量在栈上占有的内存就会自动释放。
2. 分配在托管堆中的变量并不会再创建它们的方法结束时释放内存。所占用的内存会被CLR中的垃圾回收机制释放。
string name = "Hello World";
声明一个String类型的变量name,它指向托管堆中的数据“Hello World“,当方法调用结束的时候,name在托管堆上所占用的内存会立即释放,但他在托管堆上的数据还依然存在。只不过此时可能没有变量的引用指向它了。它将持续等待直到未来时候被GC回收并释放所占内存。
三、 装箱和拆箱
当值类型的数据转换为引用类型时为装箱,反之为拆箱。
CLR会现在托管堆配置一块内存,将值类型的数据复制到这块内存,然后再让托管栈上的引用类型变量指向这块内存。反之为拆箱。
一般装箱是自动的,系统会帮我们完成,但拆箱并非自动的,我们必须知道被拆箱的对象的实际类型,然后明确地去执行拆箱操作。
托管栈中的类型为Int32值为1023的变量,装箱后引用类型变量位于栈中,原来值类型变量的值被放入托管堆中的一个对象中,其内容为1023,类型为Object,然后将位于托管栈中的引用类型变量指向堆中这个Object类型的变量,这就是装箱的整个过程。
示例代码:
Int32 number = 1023;//Int32类型的变量number
object boxingNumber = number;//系统自带装箱
Int32 unboxingNumber = (Int32)boxingNumber;//明确的拆箱
注意:装箱和拆箱堆性能是有影响的,因此它话费了更多的时间。