深入理解C#(八)
*第二章(C# 类型系统)
C# 1的类型系统是静态的、显示的和安全的
静态:描述表达式的编译时类型,使用不变的数据来分析哪些操作可用。
C# 1的类型系统何时不够用
.NET 1.1内建了三种集合类型:
- 数组–强类型–内建到语言和运行时中
- System.Collections命名空间中的弱类型集合
- System.Collections.Specialized命名空间中的强类型集合
引用类型的数组支持协变(covariance),只要元素的类型之间允许转换,就能隐式将一种数组类型转换成另一种
方法覆盖和接口实现不允许协变性/逆变性
参数类型的逆变性:使用一个放宽限制的签名如:void Process(object x)
值类型和引用类型
类是引用类型;结构是值类型
数组是引用类型;枚举是值类型
委托类型是引用类型;接口类型是引用类型,但可由值类型实现
变量存储
- 变量的值在它声明时的位置存储
- 局部变量的值总是存储在栈(stack)中(C# 1中完全成立,高级版本可能存在堆中)
- 实例变量的值总是存储在实例本身存储的地方
- 引用类型实例总是存储在堆(heap)中,静态变量也是。
关于引用传递和值传递
无论是引用传递还是值传递,永远不会传递对象本身。
详见Parameter passing in C#
关于装箱和拆箱
对于引用类型的变量,它的值永远是一个引用
对于值类型的变量,它的值永远是该值类型的一个值
int i=5;
object o=i;
int j=(int) o;
第二行,发生了装箱操作:运行时在堆上创建一个包含值(5)的对象,o的值是对该新对象的一个引用。该对象的值是原始值的一个副本,改变i不会改变箱内的值。
第三行,执行相反操作,拆箱。必须告诉编译器将object拆箱成什么类型。
装箱什么时候方式?
为一个类型的值调用ToString、Equals或GetHashCode方法时,如果该类型没有覆盖这些方法,也发生装箱。另外,将值作为接口表达式使用时也会发生装箱。
太过频繁的装拆箱会增大程序的操作开销,还会创建数量众多的对象,加重垃圾回收器的负担。