C
C#•11mo ago
MaxHayman

Inline array of struct assignment

Hey, I am trying to implement something using inline arrays, however I am struggling to get a way to do it in a clean way.
[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer10<T>
{
private T _element0;
}

public Buffer10<Header> Headers { get; set; }

public void AddHeader(Header header)
{
Headers[HeadersCount++] = header;
}
[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer10<T>
{
private T _element0;
}

public Buffer10<Header> Headers { get; set; }

public void AddHeader(Header header)
{
Headers[HeadersCount++] = header;
}
gets
Error CS0131 : The left-hand side of an assignment must be a variable, property or indexer
Error CS0131 : The left-hand side of an assignment must be a variable, property or indexer
I am sure this worked in preview .net 8. Does anyone have any experience using inline arrays yet. It feels rough having to have some kind of proxy struct and i wish you could do this on the field/property level.
14 Replies
cap5lut
cap5lut•11mo ago
the problem is more or less that u get a copy of the actual value/backing field of the auto property even if that would compile, u would not be able to observe the change u can probably fix that by having a getter that returns a ref Buffer10<Header> but then u expose the whole thing and make it mutable in every way eg like this
private Buffer10<Header> _headers;
public ref Buffer10<Header> Headers => ref _headers;
private Buffer10<Header> _headers;
public ref Buffer10<Header> Headers => ref _headers;
but i think the cleanest way here would be to split it up into a public getter only property for a ReadOnlySpan<Header> and using an explicit internal field
private Buffer10<Header> _headers;
public ReadOnlySpan<Header> Headers => MemoryMarshal.CreateReadOnlySpan(ref _headers[0], 10);
public void AddHeader(Header header) => _headers[HeaderCount++] = header;
private Buffer10<Header> _headers;
public ReadOnlySpan<Header> Headers => MemoryMarshal.CreateReadOnlySpan(ref _headers[0], 10);
public void AddHeader(Header header) => _headers[HeaderCount++] = header;
it could also be that its actually complaining about the HeadersCount++ if thats a property 🤔
MaxHayman
MaxHaymanOP•11mo ago
Do i need to implement AsSpan for my Buffer10?
cap5lut
cap5lut•11mo ago
i mixed up what the compiler generates and edited the code afterwards, u use MemoryMarshal.CreateSpan() or MemoryMarshal.CreateReadOnlySpan() for whatever u want. as u usually do not expose this buffer type directly, it most likely doesnt deserve having such a method
MaxHayman
MaxHaymanOP•11mo ago
okay its compiling now thank you, I will try and play with it I does feel very strange having the Buffer10. If I have some place that needs 10 and some which needs 10 am i expect to just have Buffer1-100 or something?
cap5lut
cap5lut•11mo ago
in the end, yes
MaxHayman
MaxHaymanOP•11mo ago
Why wouldn't they have just codegenned it and wrapped it in a way so you can declare it similar to a regular heap allocated array?
cap5lut
cap5lut•11mo ago
tbh i also dont name them that generalized but some explicit stuff for whatever i use it for, like file struct CharacterListDataBuffer<T>
MaxHayman
MaxHaymanOP•11mo ago
If its that specific why would I use T?
cap5lut
cap5lut•11mo ago
why they decided to do it like that is probably a question for #roslyn ah, its just an example from one of my buffers. i basically get a packet as response where i have max 10 entries and its either an int, ushort or a string, and u cant stackalloc reference type spans and need to use inline arrays for that
MaxHayman
MaxHaymanOP•11mo ago
Yeah we are planning to use it for packet structs I guess I feel like im not meant to use it how im using it.
cap5lut
cap5lut•11mo ago
i think u simply shouldnt expose it at all on the public API surface, there u should use Span<T> or ReadOnlySpan<T> instead because how big the internal buffer is ... is an internal implementation detail its also a thing, currently u have a length of 10, what will u do if that changes in the future? adjust the attribute parameter and rename the type? cant really do that because other types might use a Buffer10<T> as well and it would break binary and maybe source compatibility creating another type? breaks binary/source compatibility too so thats more or less the best way to do it on the API surface, most likely also in the internal
MaxHayman
MaxHaymanOP•11mo ago
Thanks for your help btw
cap5lut
cap5lut•11mo ago
glad i could help o7 if u think ur question is answered, dont forget to $close the thread
MODiX
MODiX•11mo ago
Use the /close command to mark a forum thread as answered
Want results from more Discord servers?
Add your server