Каков размер этой структуры C #?

Это 12 байтов или 16 байтов при хранении в List<DataPoint>?

public struct DataPoint
{
    DateTime time_utc;
    float value;
}

Есть ли в C # функция sizeof?


person Meh    schedule 27.09.2010    source источник
comment
Надеюсь, вы знаете, что каждый экземпляр этой структуры будет помещен в рамку при добавлении в список, поэтому добавьте место для указателя.   -  person    schedule 27.09.2010
comment
@ToxicAvenger: он не будет упакован, если вы поместите его в List<DataPoint>. Хотя это было бы заключено в ArrayList или List<object>.   -  person Ruben    schedule 27.09.2010
comment
Это более конкретно, но, возможно, дублирует заголовок stackoverflow.com/questions/3361986/   -  person Philip Rieck    schedule 27.09.2010


Ответы (6)


Взгляните на ответ @Hans Passant здесь за интересную предысторию этого вопроса, особенно. что касается ограничений Marshal.Sizeof.

person Steve Townsend    schedule 27.09.2010

CLR может размещать типы в памяти по своему усмотрению. Таким образом, невозможно прямо указать размер.

Однако для структур можно ограничить свободу среды CLR с помощью Атрибут StructLayout:

  • Авто: среда выполнения автоматически выбирает подходящий макет.
  • Последовательно: элементы объекта располагаются последовательно и выравниваются в соответствии со значением StructLayoutAttribute.Pack.
  • Явно: точное положение каждого члена контролируется явно.

Компилятор C # автоматически применяет тип макета Последовательный к любой структуре. Значение Pack по умолчанию равно 4 или 8 на машинах x86 или x64 соответственно. Таким образом, размер вашей структуры 8 + 4 = 12 (как x86, так и x64).


Вне зависимости от того, как тип размещен в памяти, можно также маршалировать тип в .NET с помощью Класс маршала. Маршаллер применяет несколько преобразований при маршалинге типа, поэтому результат не всегда совпадает с тем, как CLR размещает тип. (Например, bool занимает 1 байт в памяти плюс выравнивание, в то время как маршаллер упорядочивает bool до 4 байтов.)

person dtb    schedule 27.09.2010
comment
Обратите внимание, что с помощью инструкции IL sizeof можно получить окончательный размер CLR структуры с учетом заполнения и любых других операций выравнивания. См. мое сообщение в блоге, чтобы узнать, как его использовать, и узнать о других различиях (примечание: я написал библиотеку оболочки который можно вызвать из C #) - person Earlz; 14.11.2012

Marshal.SizeOf()

http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx

person Community    schedule 27.09.2010
comment
Вы можете добавить решение его вопроса: 16 байтов (8 байтов + 4 байта + 4 байта выравнивания) - person Scoregraphic; 27.09.2010
comment
Marshal.SizeOf () не возвращает размер управляемой структуры, только ее неуправляемую версию. Проверьте ответ Стива. - person Hans Passant; 27.09.2010

Это будет 12 байтов (4 для float, 8 для DateTime); Marshal.SizeOf вернет 16, потому что по умолчанию упаковка выровнена по 8 байтов. Это хорошая статья о структурах и упаковке. Он дает полное описание того, что происходит на самом деле.

person SwDevMan81    schedule 27.09.2010

Попробуйте Marshal.SizeOf (typeof (DataPoint))

person elsni    schedule 27.09.2010

Следующий код основан на этом вопросе StackOverflow и ответах < / а>:

        /// <summary>
        /// Computes the size of the given managed type. Slow, but reliable. Does not give the same result as Marshal.SizeOf
        /// NOTE: this is not the same as what is the distance between these types in an array. That varies depending on alignment.
        /// </summary>
        public static int ComputeSizeOf(Type t)
        {
            // all this just to invoke one opcode with no arguments!
            var method = new DynamicMethod("ComputeSizeOfImpl", typeof(int), Type.EmptyTypes, typeof(Util), false);
            var gen = method.GetILGenerator();
            gen.Emit(OpCodes.Sizeof, t);
            gen.Emit(OpCodes.Ret);
            var func = (Func<int>)method.CreateDelegate(typeof(Func<int>));
            return func();
        }

Я думаю, что вопрос, который вы, вероятно, задаетесь вопросом, заключается не в том, каков размер типа, а в том, каково расстояние между двумя смежными элементами в списке. Это потому, что выравнивание может играть роль, как упоминали другие.

Я считаю, что решение этой проблемы лучше всего будет достигнуто с помощью _ 2_, но его очень сложно правильно использовать, особенно потому, что List не раскрывает публично резервный массив.

person cdiggins    schedule 14.01.2019