Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Array's Length property

Tags:

arrays

c#

unity3d

Is it possible to change an array's Length property with some technique?

I need to pass first x members of an array to a method. The project requirements prevent me from allocating any heap allocation so I can't use any Array.Resize() or create a new array.

Also I can't change the SetVertices code because it belongs to another library. It needs V[]. I can't pass IList<V> or V* to it.

public void BuildIt(V[] verts,int x){
    verts.Length = x; //Compile error
    mesh.SetVertices(verts);
}

Of course the code won't compile. I need some technique like reflection or extension methods to disguise the array as smaller without actually creating an smaller array. I want SetVertices() method to think the array has x members even though it has more.

EDIT:

Tested the following approaches and they don't work:

  • stackalloc doesn't work because it doesn't create (or I couldn't get) a real array.
  • Peeking into mono project I found out that array's Length property is calling GetLenght() and GetRank() methods to determine the length. Being a bad practice aside, I can't override this method with extension methods because instance methods have precedence over extension methods(or is there a way to force otherwise?).

Gonna try code injection next.

EDIT2:

Tried to emit code into Array.GetLength() and Array.Length. It seems there is no easy, reliable, cross platform and clean way to change an existing method body at runtime.

like image 491
morteza khosravi Avatar asked Dec 24 '15 08:12

morteza khosravi


2 Answers

If you really have to do this with maximum performance - then you must know memory layout for particular CLR you use (seems to be some version of Mono in your case). Then you are able to do some unsafe code that change and restore array length. But it's not maintainable and dangerous.

like image 151
Valery Petrov Avatar answered Nov 19 '22 05:11

Valery Petrov


If the arrays and x are not changing and their number is not to big, then you could allocate them once globally, not locally. So, you would invest memory and gain performance.

like image 22
Dieter Meemken Avatar answered Nov 19 '22 06:11

Dieter Meemken