我正在尝试序列化具有任意数量维度的多维数组。请注意,我指的是实际的多维数组(float [,]),而不是锯齿状数组(float [] [])。
序列化每个维度的长度后,我可以使用foreach(数组中的var项目)轻松序列化每个元素。
但是反序列化时我不能使用foreach因为我需要赋值。我知道我需要使用array.SetValue(对象值,params int []索引),但我无法解决如何设置循环以执行通常使用一个嵌套for循环执行的操作对于每个维度。
答案 0 :(得分:1)
首先,使用foreach
循环序列化原始数组。它会使阵列变平。
然后,以与序列化相同的方式读取值(代码基于数组的enumerator)
var original = new int[2,2,2] { { { 1, 2 }, { 3, 4} }, { { 5, 6 }, { 7, 8 } } };
var serialized = original.Cast<int>().ToArray();
var originalBounds = Enumerable.Range(0, original.Rank)
.Select(i => original.GetUpperBound(i) + 1).ToArray();
var empty = Array.CreateInstance(typeof(int), originalBounds);
var indices = new int[empty.Rank];
indices[indices.Length - 1]--;
var index = 0;
while (IncArray(empty, indices))
{
empty.SetValue(serialized[index++], indices);
}
private bool IncArray(Array array, int[] indices)
{
int rank = array.Rank;
indices[rank - 1]++;
for (int i = rank - 1; i >= 0; i--)
{
if (indices[i] > array.GetUpperBound(i))
{
if (i == 0)
{
return false;
}
for (int j = i; j < rank; j++)
{
indices[j] = 0;
}
indices[i - 1]++;
}
}
return true;
}
这种方法允许您从流中读取值 - 您不需要像我一样创建serialized
数组。
另一种方法是使用Buffer.BulkCopy
。在这里,您必须读取整个数组,至少以字节为单位,并计算您需要复制的字节数。这里的优点是你可以避免使用上一个方法中的所有装箱,并且它更简单:
var bytes = new byte[...]; // read the entire byte array
var empty = Array.CreateInstance(typeof(int), originalBounds);
Buffer.BlockCopy(bytes, 0, empty, 0, bytes.Length);