好的,我冒昧地假设您指的是数组数组而不是二维数组,否则该转换将无法编译
多维数组 [][] vs [,]
公平地说,这很令人困惑!
当谈到弄清楚代码是如何工作的时,只要有一个小提琴就永远不会受到伤害。我敲了一些虚拟代码以表明您所做的只是创建对内存的新引用而不是创建副本。
object[][] obj = new object[5][]; //Delcare Jagged array
obj[0] = new object[] { 1, 1, 1 };
obj[1] = new object[] { 2, 2, 2 };
obj[2] = new object[] { 3, 3, 3 };
obj[3] = new object[] { 4, 4, 4 };
obj[4] = new object[] { 5, 5, 5 }; //Fill up with stuff
Console.WriteLine("{0}", obj[2][0]); // prints 3
object[] newobj = (object[])obj; // Declare array of objects and cast
newobj[2] = new object[] { 9, 9, 9 }; // update using the new refrence
Console.WriteLine("{0}", obj[2][0]); // print from old reference, now prints 9
Console.WriteLine("{0}", ((object[])newobj[2])[0]); // print from new reference, prints 9 but requires a cast
Console.WriteLine("{0}", newobj[2][0]); // Error, cannot apply indexing with [] to an expression of type object
所以你可以看到从新的一维引用更新数组仍然会更新原始引用仍然指向的底层内存。但是,正如您向编译器坚持的那样,第二个引用是一维数组,您不能再使用 [][] 语法,或者至少不能再次使用强制转换
您还可以使用ILSpy等工具来查看代码是如何编译的。在这种情况下,我们的函数在顶部声明了两个局部类型
.locals init (
[0] object[][],
[1] object[]
)
但是当转换发生时,IL 所做的只是将变量 0 的值(引用)压入堆栈并将其弹出到变量 1 中,就这么简单!
IL_00ca: ldloc.0 //push 0
IL_00cb: stloc.1 //pop 1