数组类中的大多数方法只适用于一维数组,因此您必须手动执行复制:
T[,] ResizeArray<T>(T[,] original, int rows, int cols)
{
var newArray = new T[rows,cols];
int minRows = Math.Min(rows, original.GetLength(0));
int minCols = Math.Min(cols, original.GetLength(1));
for(int i = 0; i < minRows; i++)
for(int j = 0; j < minCols; j++)
newArray[i, j] = original[i, j];
return newArray;
}
要了解为什么它不适用于Array.Copy,您需要考虑内存中多维数组的布局。数组项真正存储为二维数组,它们是连续存储的,一行接一行。所以这个数组:
{ { 1, 2, 3 },
{ 4, 5, 6 } }
实际上是这样排列在内存中的:{ 1, 2, 3, 4, 5, 6 }
现在,假设您想再添加一行和一列,这样数组看起来像这样:
{ { 1, 2, 3, 0 },
{ 4, 5, 6, 0 },
{ 0, 0, 0, 0 } }
现在内存中的布局如下:{ 1, 2, 3, 0, 4, 5, 6, 0, 0, 0, 0, 0 }
但Array.Copy 将所有数组视为一维。 MSDN 说:
在多维数组之间复制时,数组的行为类似于一个长的一维数组,其中行(或列)在概念上是首尾相连的
因此,当您尝试将原始数组复制到新数组时,它只是将一个内存位置复制到另一个内存位置,从而以一维表示形式给出:
{ 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0 }.
如果将其转换为二维表示,则会得到以下结果:
{ { 1, 2, 3, 4 },
{ 5, 6, 0, 0 },
{ 0, 0, 0, 0 } }
这就是为什么您会得到一个搞砸的数组...请注意,如果您更改行数而不是列数,它将起作用。