关于基础类型
小结:
1. 关于值类型与引用类型
a. 值类型在线程栈上分配,不受垃圾回收器的控制,减少了托管堆的作用,所有的值类型都继承自System.ValueType, 后者继承自System.Object。
b. 引用类型在托管堆上分配,受垃圾回收器的控制。
c. 装箱与拆箱
装箱做了哪些操作?
1)统计值类型转引用类型所需的字节数 = 值类型本身所需要的字节数 + 类型对象指针 + 同步块索引
2)在托管堆上分配空间
3)把值类型中的域拷贝到分配的空间中
4)返回在堆中的地址
拆箱做了哪些操作?是不是装箱的相反过程?答案是否定的
拆箱中只把托管堆中的域拷回给值类型,但并不会拷贝类型对象指针以及同步块索引,所以拆箱的开销比装箱的开销小的多
在拆箱的时候如果要进行类型转换的话得注意,只能先拆成其原先的类型,然后再进行转换,而不能一步到位,如:
Int32 x = 15;
Object o = x; //装箱
Int16 y = (Int16)o;//拆箱,这时会抛出一个不合法转换异常
正确的做法是:
Int32 x = 15;
Object o = x;
Int16 y = (Int16)(Int32)o;
----优先使用泛型,尽量少使用装箱与拆箱
2. 关于Equals 和 "==" 运算符
针对于值类型和引用类型,引用类型中把String类单独取出
a. 对于Equals
无论是值类型、引用类型【除String类的其他引用类型】、还是String类型,比较的都是存储信息的内容
b. 对于 "=="
只有在比较引用类型时【除String类的其他引用类型】,才是比较引用类型在栈中的地址,其他【含String类】比较的都是存储信息的内容
3. 关于dynamic类型
1) 这种类型变量只有在Runtime时才可以确定其具体类型,类似于反射,然后根据其具体类型做与此类型相对应的操作,如:
方法定义:
private dynamic Add(dynamic arg){return arg + arg;}
方法调用1:
dynamic x = 5;
dynamic result = Add(x);
----结果是:10
方法调用2:
dynamic x = "A";
dynamic result = Add(x);
----结果是:AA
2) dynamic 与 var的区别
a. var只能在方法体内声明本地变量,而dynamic可以声明本地变量、域、参数
b. 必须初始化var变量,但可以不初始化dynamic变量
c. 不能将一个表达式转换成var, 但可以转换成dynamic