Разобравшись с InlineArray и SkipLocalsInit мы можем пойти дальше. Например, мы можем представить любую структуру как
Span. Напомню, что Span это простой указатель на адрес в памяти + отступ, умноженный на размер элемента Span'a. Сделать Span из структуры достаточно просто:
private struct MyStruct {
private int _item0;
...
private int _item9;
}
// Пропускаем инициализацию структуры
Unsafe.SkipInit(out MyStruct myStruct);
// Получаем ссылку на структуру на стеке
ref var reference = ref Unsafe.As<MyStruct, int>(ref myStruct);
// Получаем структуру как спан
var span = MemoryMarshal.CreateSpan(ref reference, MyStructItemCount);Представляется, что примерно так работает представление структуры, отмеченной InlineArrayAttribute, когда мы говорим
Span<int> span = myInineArray. Бенчмарк подтверждает это, так как скорость доступа к элементам структуры близка к прямому доступу через индексатор InlineArray.Представление структуры как
Span позволяет проще обращаться к элементам структуры (например, без монструозных switch), а именно её заполнение или чтение. При этом, нам надо быть крайне аккуратными, так как методы статического класса
Unsafe очень не зря находятся в этом классе. Пусть нас не обманывает простота их использования - фактически это тот же unsafe-код.
