Now try to answer why this is not possible.
C # is a safe type. This means that only certain conversion (casting) is allowed on compatible types. This explains why this code is not allowed:
Vector2f[] structs; float[] floats = (float[])structs;
In fact, C # uses references instead of pointers. One of the differences is that the link is not a static location in memory. The object can be moved during garbage collection.
However, C # allows some pointer arithmetic with unsafe code. To do this, the garbage collector must be notified that the memory should not be moved (and that the links should not be invalidated) for the objects in question. This is done using the fixed keyword.
In other words, to get a pointer to a reference object (the same logic for the structure), you first need to freeze the location of the object in memory (this is also called pinned memory):
fixed (Vector2f* pStructs = structs) fixed (float* pFloats = floats) { ...
Now that everything is set, you cannot change the address of these pointers. For example, this is not valid:
pFloats = (float*)pStructs
Also, you cannot convert the pointer back to a link:
float[] floats = (float[])pFloats;
In conclusion, as soon as you get a pointer, you can move several bytes from one place to another, but you cannot change the location of the corresponding links (only data can be moved).
Hope the answer to your question.
As an additional note , if you have many critical operations, you can consider implementing it in C ++, expose some high-level functions, and call some functions from C #.