Это 12 байт или 16 байт, если они хранятся в List<DataPoint>
?
public struct DataPoint
{
DateTime time_utc;
float value;
}
Есть ли функция sizeof в С#?
Это 12 байт или 16 байт, если они хранятся в List<DataPoint>
?
public struct DataPoint
{
DateTime time_utc;
float value;
}
Есть ли функция sizeof в С#?
Взгляните на @Hans Passant answer здесь для интересного фона по этой проблеме, особенно. в отношении ограничений Marshal.Sizeof
.
Marshal.SizeOf()
CLR может свободно размещать типы в памяти по своему усмотрению. Поэтому невозможно прямо указать размер ".".
Однако для структур можно ограничить свободу CLR, используя StructLayout Attribute:
Компилятор С# автоматически применяет вид макета Sequential для любой структуры. Значение Pack по умолчанию равно 4 или 8 на машинах x86 или x64 соответственно. Таким образом, размер вашей структуры равен 8 + 4 = 12 (как x86, так и x64).
Несвязанный из того, как выкладывается тип в памяти, также возможно маршалировать тип в .NET с помощью класса маршала. Маршаллер применяет несколько преобразований при сортировке типа, поэтому результат не всегда совпадает с тем, как CLR выложил тип. (Например, a bool
занимает 1 байт в памяти плюс выравнивание, в то время как маршаллер маршалирует от bool
до 4 байтов.)
Это будет 12 байт (4 для float, 8 для DateTime);
Marshal.SizeOf
вернет 16, потому что стандартная упаковка равна 8 байтам.
Это - хорошая статья о структурах и упаковке. Он дает полное описание того, что на самом деле происходит.
Попробуйте Marshal.SizeOf(typeof (DataPoint))
Следующий код основан на fooobar.com/info/4267655/...:
/// <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
не предоставляет публично доступный массив поддержки.