如何设置多维系统中每个元素的值.未知等级数组



我正在尝试序列化具有任意数量维度的多维数组。请注意,我指的是实际的多维数组(float[,]),而不是交错数组(float[][])。

序列化每个维度的长度后,我可以使用 foreach(数组中的 var 项)轻松序列化每个元素。

但是在反序列化时,我不能使用 foreach,因为我需要分配值。我知道我需要使用数组。SetValue(对象值,参数 int[] 索引),但我无法弄清楚如何设置一个循环来执行您通常对每个维度的嵌套 for 循环所做的事情。

首先,使用 foreach 循环序列化原始数组。它将展平阵列。

然后,以与序列化相同的方式读取值(代码基于数组的枚举器)

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);

相关内容

  • 没有找到相关文章

最新更新