Is it possible to use `Span` with a type erased `System.Array` created with `Array.CreateInstance`?
I am working on a C# ECS which stores its components in an archetype which contains an array of arrays. The outer arrays represent the various component types of the ECS (velocity, position), and the inner arrays represent all of the components of that type in the archetype (position 1 with x = 1, position 2 with y = 5). I want to be able to move components between arrays while avoiding copying in cases where it's unnecessary, even when the type is a value type. Ideally, I would be able to get references to items in this array, which I can pass into methods which expect that reference (these will probably be generic). Right now I'm pretty much always using
Array.Copy
, which doesn't allow me to get references to the array. Is there a way to obtain Span
s or references from a type erased Array
?41 Replies
I guess an array of references isn't even possible in C#
Technically all ref-types are already refed in C#, the
ref
keyword is a double reference and different to C/C++.
Speaking of which and taking an example on a ref-type like string
, string
is immutable in C# which will and must result in a different pointer address.As seen, the arrays and variables share all the same pointer since they point a variable created before
string a = "hello";
If you want to hold the reference wrap it in an ref-type
object
like a class
or record
since the pointer of the object
won't change but only the one from it's child property. This will not work with a value-type like a struct
.The goal is pretty much to be able to return an array of references to structs. I think the wrapper type idea will probably work to get around that
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Basically, you can ask for a reference to a struct to modify its fields, even though it's a value type, because the variable itself is a reference type
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Yeah, I think I might be boxing anyways... Not sure whether Array.CreateInstance actually avoids this
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Because I don't want to box and unbox when I copy between arrays of the same type
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Yes, that's what I'm using
Also, I don't know the types of what I'm storing
I have a
Type[]
array that tells me at runtimeUnknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Yeah, new doesn't work when the type is in a
Type
value unfortunatelyUnknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Sure, this is what I have now: https://gist.github.com/cjhowedev/efa28aa75258b5ace3f513e640d320aa
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Everything is type erased and yet I want to avoid boxing
Using generics, ref structs, etc.
This has to be fast, pretty much
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Well, it's okay for some operations in this case
The adding/removing components is fine to use boxing
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Basically, I'm going to do queries that have to be high performance, that will let you mutate things in place (no adding/removing/moving components)
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Nah, it's System.Array
You would only do this for this situation AFAIK
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Is it though?
object[]
can store different types: [1, "hello", false]
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Array.CreateInstance(type, 2)
can only store instances of type
And that's what I wantUnknown User•9mo ago
Message Not Public
Sign In & Join Server To View
What I'm doing is a little out there, but it's pretty much a high performance parallel ECS. Since I will be running a great deal of queries on a great deal of entities, and I don't want to serialize all mutation, I want to allow in place edits of structs. This should be faster than using a class reference type I think?
Yes, that's pretty much unavoidable. I don't know component types in advanced
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
I don't think so
Like, think of it this way: even if I know all combinations of components at compile time that are used with my functions, you can add two different sets of components to the same entity. So this means I can't determine the actual types an entity might have until runtime
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
In the future I will likely need to use something lower level than arrays...
I don't know if such a thing exists yet
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
TeBeCo
it's basically
object[]
Quoted by
<@689473681302224947> from #Is it possible to use
Span
with a type erased System.Array
created with Array.CreateInstance
? (click here)React with ❌ to remove this embed.
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
BTW, this is like the 3rd or 4th language I've written this code in; it's definitely possible in C++. But not sure storing managed objects in unmanaged C++ memory is a great idea
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Definitely something for #allow-unsafe-blocks 🙂
This
IEnumerable<IEnumerable<object>>
is enough to give me creeps, only dynamic
could make it more frightening to me 🙂