Use of inline arrays to model arrays of structs
For a native type with the following shape:
it occurred to me I could represent the sequential
CHRDATA
s with an InlineArray
as such:
which raises a few questions, since I'm unfamiliar with the feature:
1) is this legal? can you make InlineArrays
of blittable structs, or should usage of InlineArray
be restricted to primitives? (i.e. int
, float
)
2) does chrs[62].hp = 300;
in the above case operate on a copy or actually mutate the relevant part of SAVEDATA
?12 Replies
1) try compile and see
2) the indexer returns the ref to
CHRDATA
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-12.0/inline-arrays#when-the-expression-type-is-intInline arrays, or fixed sized buffers - C# feature specifications
Inline arrays provide a general-purpose and safe mechanism for declaring inline arrays within C# classes, structs, and interfaces.
alright, that clears it up, just one follow-up: if one of these was special and I wanted to provide a named accessor, by putting a property on
CHRDATA_ARRAY
like:
I assume this will not return ref CHRDATA
- is there a way to make that happen? if I try:
it fires CS9084: Struct member returns 'this' or other instance members by reference
, but I've not been able to find documentation for thisyou can work around this by slapping
[UnscopedRef]
on the getter
or make an extension method that takes in a ref:HmmNoted:
Thanks, I'll write that down somewhere
You may get in hot water with this, since you’ve got a ref to something that might be in the stack that the compiler doesn’t know is in the stack anymore…
Any reason to not just add a setter and skip the dangers of ref?
Heck, you might have a ref to a struct that doesn’t even really exist anymore (if it made a copy of the struct to call this method on).
in this case, the structs are just mapping/projection for something at a fixed location in memory in a subordinate native process
in that sense, I don't know what would have to occur for them to move, and they're not intended to be 'used' as such in regular calls
I guess if you have some fixed pointer to a native, returning a ref is... probably safe...? Though "safe" is certainly an interesting word when working with pointers. 🙂 I'm surpzied the compiler bothered warning you about that in an unsafe context.
you do not get in hot water for this
Aaron
REPL Result: Failure
Exception: CompilationErrorException
Compile: 376.485ms | Execution: 0.000ms | React with ❌ to remove this embed.
the compiler keeps track of this and does not let you do invalid things with refs
it does warn you about this in an unsafe context, but only because it is normally an outright error and you really shouldn't be doing it
they were not in one when they tried this anyway, I don't think
Aaron
REPL Result: Success
Compile: 274.488ms | Execution: 39.816ms | React with ❌ to remove this embed.
(there is a warning there still, the repl just doesn't show warnings)
but yeah,
[UnscopedRef]
isn't "shut up and do what I want, who cares about safety", it does something very specific and restricts how callers can use the ref that is returned