Мне нужна фиксированная структура данных, которая (по соображениям производительности) управляется в стеке, но ведет себя как массив

Я знаю, что могу создать что-то вроде этого:

using System;

namespace X
{
    public sealed struct CustomArray<T>
    {
        private const Int32 n = 2;

        private T _field_1;
        private T _field_2;
        // ...
        private T _field_n;

        public T this[Int32 idx]
        {
            get
            {
                switch(idx)
                {
                    case (0): return _field_1;
                    case (1): return _field_2;
                    // ...
                    case (n): return _field_n;

                    default: throw new IndexOutOfRangeException();
                }
            }
            set
            {
                switch(idx)
                {
                    case (0): _field_1 = value; break;
                    case (1): _field_2 = value; break;
                    // ...
                    case (n): _field_n = value; break;

                    default: throw new IndexOutOfRangeException();
                }
            }
        }
    }
}

Но это не очень удобно для структур, состоящих из ~ 50 элементов. есть ли способ сделать это более удобным и легким в обслуживании способом?

Спасибо вперед

3
Benj 4 Мар 2015 в 10:12

2 ответа

Лучший ответ

Вы можете выделить массив в стеке с помощью ключевого слова stackalloc, похоже, это будет удовлетворить ваши потребности в распределении стека. К сожалению, это требует, чтобы вы были в небезопасном контексте.

int* block = stackalloc int[100];
3
Sriram Sakthivel 4 Мар 2015 в 07:25

Другая альтернатива - объявить структуру данных с именованными полями как структуру и создать ее в стеке (как локальную переменную). Если вам нужен массив, например доступ к данным в стеке, вы можете сделать что-то вроде этого:

[StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]
public unsafe struct DataStructure
{
    [FieldOffset(0)]public fixed ushort[8];

    [FieldOffset(0)]public ushort wYear; 
    [FieldOffset(2)]public ushort wMonth;
    [FieldOffset(4)]public ushort wDayOfWeek; 
    [FieldOffset(6)]public ushort wDay; 
    [FieldOffset(8)]public ushort wHour; 
    [FieldOffset(10)]public ushort wMinute; 
    [FieldOffset(12)]public ushort wSecond; 
    [FieldOffset(14)]public ushort wMilliseconds; 
}

Тогда вы можете ссылаться на это так:

private static unsafe void Main(string[] args)
{
    DataStructure ds;

    ds.wYear = 2015;
    ds.wMonth = 04;

    ds.array[0] = 2014;
    ds.array[1] = 05;
}
1
Paul 4 Мар 2015 в 07:39