这是基于建议的解决方案阿列克谢·列文科夫 https://stackoverflow.com/users/477420/alexei-levenkov在评论中。从他的评论来看:做某事最快的方法就是根本不做...这对你的情况有效吗(即通过将所有 4 个都包装到一个以你喜欢的方式公开索引的类中)?
您创建四个单独的数组,然后将它们添加到能够将这些数组保存在矩形数组中的包装器中。我使用一个函数来访问各个元素,但您可以使用索引器来代替(如果您倾向于这种方式 - 我不喜欢,该访问器对于简单的索引器来说似乎有点太复杂)。
这是主要的类:
public class CompositeArray<T> where T:new()
{
private readonly T[,][,] _componentArray = null;
public int IndividualArrayWidth { get; }
public int IndividualArrayHeight { get; }
public int ComponentArrayWidth { get; }
public int ComponentArrayHeight { get; }
public int OverallArrayWidth => IndividualArrayWidth * ComponentArrayWidth;
public int OverallArrayHeight => IndividualArrayHeight * ComponentArrayHeight;
public CompositeArray(int individualArrayWidth, int individualArrayHeight, int componentArrayWidth,
int componentArrayHeight)
{
IndividualArrayWidth = individualArrayWidth;
IndividualArrayHeight = individualArrayHeight;
ComponentArrayWidth = componentArrayWidth;
ComponentArrayHeight = componentArrayHeight;
_componentArray = new T[ComponentArrayWidth, ComponentArrayHeight][,];
}
public void SetIndividualArray(int x, int y, T[,] array)
{
if (x < 0 || x >= IndividualArrayWidth)
{
throw new ArgumentOutOfRangeException(nameof(x), x, $@"Must be between 0 and {IndividualArrayWidth - 1}");
}
if (y < 0 || y >= IndividualArrayHeight)
{
throw new ArgumentOutOfRangeException(nameof(y), y, $@"Must be between 0 and {IndividualArrayHeight - 1}");
}
if (array.GetLength(0) != IndividualArrayWidth || array.GetLength(1) != IndividualArrayHeight)
{
throw new ArgumentOutOfRangeException(nameof(array), $@"Must be between an array that is {IndividualArrayWidth} by {IndividualArrayHeight}");
}
_componentArray[x, y] = array;
}
public T GetOverallElement(int x, int y)
{
if (x < 0 || x >= OverallArrayWidth)
{
throw new ArgumentOutOfRangeException(nameof(x), x, $@"Must be between 0 and {OverallArrayWidth - 1}");
}
if (y < 0 || y >= OverallArrayHeight)
{
throw new ArgumentOutOfRangeException(nameof(y), y, $@"Must be between 0 and {OverallArrayHeight - 1}");
}
int whichArrayX = x / IndividualArrayWidth;
int innerX = x % IndividualArrayWidth;
int whichArrayY = y / IndividualArrayHeight;
int innerY = y % IndividualArrayHeight;
return (_componentArray[whichArrayX, whichArrayY][innerX, innerY]);
}
}
请注意,我创建了一个矩形锯齿状矩形阵列。花了一些时间才弄清楚语法。
请注意,根本没有复制。对于每个元素访问,您只需支付两次整数除法和两次整数模运算的费用。如果您只使用 2x2 数组,则可以将其减少为两个位移位和两个位测试(因为除以二是一个简单的位移位,而检查偶数/奇数只是对最低有效位的测试)。
下面是一些练习该类的代码:
int[,] array00 = new int[,]
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[,] array01 = new int[,]
{
{11, 12, 13},
{14, 15, 16},
{17, 18, 19}
};
int[,] array10 = new int[,]
{
{21, 22, 23},
{24, 25, 26},
{27, 28, 29}
};
int[,] array11 = new int[,]
{
{31, 32, 33},
{34, 35, 36},
{37, 38, 39}
};
CompositeArray<int> bigArray = new CompositeArray<int>(array00.GetLength(0), array00.GetLength(1), 2,2);
bigArray.SetIndividualArray(0, 0, array00);
bigArray.SetIndividualArray(0, 1, array01);
bigArray.SetIndividualArray(1, 0, array10);
bigArray.SetIndividualArray(1, 1, array11);
var shouldBe2 = bigArray.GetOverallElement(0, 1);
var shouldBe6 = bigArray.GetOverallElement(1, 2);
var shouldBe28 = bigArray.GetOverallElement(5, 1);
var shouldBe16 = bigArray.GetOverallElement(1, 5);
var shouldBe32 = bigArray.GetOverallElement(3, 4);