First, serialize the original array using a foreach loop. It will flatten the array.
Then, read the values in the same way the were serialized (code is based on the array's 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;
}
This approach would allow you to read the values from a stream - you don't need to create the serialized array like I have.
Another way is to use Buffer.BulkCopy. Here you'd have to read the entire array, at least into bytes, and calculate the amount of bytes you need to copy. The advantage here is that you avoid all the boxing in the previous method, and that it's simpler:
var bytes = new byte[...]; // read the entire byte array
var empty = Array.CreateInstance(typeof(int), originalBounds);
Buffer.BlockCopy(bytes, 0, empty, 0, bytes.Length);
Rankproperty), and correctly serialized data representing an array will contain information within to tell you this information so you can allocate an appropriately-sized array. Please provide a good minimal reproducible example that clearly illustrates your scenario and explain exactly what you've tried and why that didn't work. Without that information, there are just far too many possibilities for this question to be useful or for it to be clear what answer you need. - Peter Duniho