0

I know that there is already a question about converting a multidimensional array into a one dimensional one, but all of the answers to it are inefficient. All of them are based around making a copy of the array, which is unnecessary. A multidimensional array (not jagged) is stored in a contiguous block of memory, so converting back and forth between a one dimensional interpretation of this block and a multidimensional interpretation should not involve copying the whole array, but instead should be essentially free. It should actually be possible to have the two arrays share the same memory, so that when one gets updated, the other one also does.

Can this be done in C#?

7
  • You can convert from single dimension indices to two-dimensional indices and vice versa with some simple math. Commented Jul 16, 2020 at 15:49
  • @RobertHarvey I know I can do it myself, but I am asking if I can make the language do it for me. Commented Jul 16, 2020 at 15:50
  • Not without copying the arrays. Have a look here: stackoverflow.com/a/16790720 Commented Jul 16, 2020 at 15:51
  • 1
    Why do you feel you need both representations of the array? And is this for all types that an array can contain or some specific type (e.g. if you are talking specifically about byte[] for instance)? Commented Jul 16, 2020 at 15:52
  • @Damien_The_Unbeliever The data is actually a 3D array. The problem is that I have a function that takes only one dimensional parameters as an argument that I must give this array to. In this case it is UnityEngine.Texture3D.SetPixelData. Because this is texture data it can only be made out of basic arithmetic types such as bytes, ints, floats, uints and structs made out of these types, such as Vector3 (three floats) if that is possible. Commented Jul 16, 2020 at 15:58

2 Answers 2

1

No, you cannot. Quite apart from anything else, arrays, like many things in .NET are objects. That means that they have an object header positioned immediately before other memory used for storing their representation.

Logically, you cannot have two different object headers, for two different types of objects, occupying the same location in memory.

Sign up to request clarification or add additional context in comments.

Comments

1

Well, the data itself if pretty much stored the same way, but the wrapping around that - the managed array type - is what's stopping you from accessing it directly.

The managed array, as Damien pointed out, has different headers for one or multidimensional kinds, for example, multidimensional array's header has more fields - to store the dimension values.

The arrays themselves are maintained by IL and GC and their "data memory" part could not be "frozen" so that the headers could be swapped from one to another, if you'd want to write directly to RAM to switch them.

I'm also concerned that there is an XY problem. Why indeed are you trying to convert one array to another? Is there a reason you cannot just use this instead?

public static T Get<T>(this T[] array, int x, int y, int maxX)
{
    return T[x + y * maxX];
}

Or even write your own wrapper around an array and provide both Get[index/indices] methods from there?

2 Comments

There is nothing stopping me from accessing the array manually, in the way you showed. I asked because I thought that it must be possible to do it somehow, as in C or C++ I could just do a quick static_cast to go around the type enforcement. It seems a little strange that there is nothing such as this in C#, but after all, its not really designed for low-level usage like uploading data to graphics memory.
@enthusiastic_3d_graphics_pr... I don't really see how uploading data to video memory is connected to how C# code access some array - via one index or two. The latter is just a question of convenience, in my opinion.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.