Каков размер этой структуры C #? - PullRequest
10 голосов
/ 27 сентября 2010

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

public struct DataPoint
{
    DateTime time_utc;
    float value;
}

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

Ответы [ 6 ]

14 голосов
/ 27 сентября 2010

Посмотрите на ответ @Hans Passant здесь , чтобы узнать интересную информацию по этому вопросу, особенно с учетом ограничений Marshal.Sizeof.

7 голосов
/ 27 сентября 2010

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

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

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

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


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

7 голосов
/ 27 сентября 2010
3 голосов
/ 27 сентября 2010

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

0 голосов
/ 14 января 2019

Следующий код основан на этом вопросе и ответах 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();
        }

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

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

0 голосов
/ 27 сентября 2010

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

...