2.1 int[]是值类型还是引用类型?
在.NET中的数组类型和C++中区别很大,.NET中无论是存储值类型对象的数组还是存储引用类型的数组,其本身都是引用类型,其内存也都是分配在堆上的。它们的共同特征在于:所有的数组类型都继承自System.Array,而System.Array又实现了多个接口,并且直接继承自System.Object。不同之处则在于存储值类型对象的数组所有的值都已经包含在数组内,而存储引用类型对象的数组,其值则是一个引用,指向位于托管堆中的实例对象。
下图直观地展示了二者内存分配的差别(假设object[]中存储都是DateTime类型的对象实例):
在.NET中CLR会检测所有对数组的访问,任何视图访问数组边界以外的代码都会产生一个IndexOutOfRangeException异常。
2.2 数组之间如何进行转换?
数组类型的转换需要遵循以下两个原则:
(1)包含值类型的数组不能被隐式转换成其他任何类型;
(2)两个数组类型能够相互转换的一个前提是两者维数相同;
我们可以通过以下代码来看看数组类型转换的机制:
// 编译成功 string[] sz = { "a", "a", "a" }; object[] oz = sz; // 编译失败,值类型的数组不能被转换 int[] sz2 = { 1, 2, 3 }; object[] oz2 = sz; // 编译失败,两者维数不同 string[,] sz3 = { { "a", "b" }, { "a", "c" } }; object[] oz3 = sz3;