第五章 基元类型、引用类型、值类型 CLR学习第五课 狼

一、基元类型:编译器直接支持的数据类型称为基元类型(如int类型其对于的是system。int32)。
二、类型溢出,可以用checked 和unchecked进行类型溢出检查和不进行类型溢出检查。一个奇怪的问题,2个byte类型相加的结果居然是个int类型。如果原因是在clr(clr只在32位何64位进行算术运算)中计算时,要把byte类型先转换为32位的int类型在相加,所以导致2个byte类型相加的结果是int类型;
一个诡异的问题 :如 a、b是byte类型 b+=a;则不会出错。
三、所以的值计算都有对应的 System.Decimal是一个特殊的类型,clr没有直接操作Decimal的值的IL代码,如果对decimal的值操作没有安全的执行,总是跑出system.overflowexception的异常,不管是否使用unckeck或者check。

四、值类型、引用类型;
值类型:直接或者间接继承自system.valueType。值类型总是从栈分配内存。
引用类型:总是从托管堆中分配内存,new返回的是对象位于托管堆中的内存地址。该地址执行对象占用的数据位。

实例化一个引用类型包必须分配2个地址。一个是数据保存的真实地址,一个是指向该真实数据的地址。

装箱:把值类型转换为引用类型。先从托管堆中为新生成的引用类型分配内存,内存大小为值类型本身的大小,再加上额外的信息(即2个附件成员,一个是指向该内存的地址的引用地址,一个是SyanBlockIndex,用于进程操作,资源释放标志物)。再将值类型拷贝到分配的空间上,在返回该值地址的语言。

拆箱:把引用类型转换为值类型。如果该引用为空,抛出NullReferenceException。如果该引用对象不是一个期望的值类型,抛出一个InvalidCstException的异常。最后返回一个保护在装箱中值类型所在真实地址的指针。

五、在一个方法体中,如果该对象是一个值类型。如果其调用的方法是引用类型的方法,该对象必须先转换为引用类型(发生装箱操作),然后再调用引用类型的方法。如果其掉用的是值类型的方法,就不会发生装箱操作。如果一个值类型调用一个引用类型的方法两次,只有在第一次调用时引发装箱操作。第二次的时候直接在托管堆中调用第一次已装箱的对象。

原文地址:https://www.cnblogs.com/gowhy/p/2007419.html