1. В одном ответе на этой странице предлагается использовать внутреннюю функцию Marshal.SizeOfType
, но это работает только для структур, которые не содержат никаких управляемых ссылок.В .NET 4.7 он выдает ArgumentException
при передаче ссылочного типа (class
) или тип struct
, содержащий встроенные ссылки.
2. Другой ответ здесь предлагает использовать код операции IL sizeof
.Это работает корректно для всех типов значений struct
, включая обобщенные и типы со встроенными ссылками, но для ссылочных типов всегда возвращается IntPtr.Size
(, т. Е. значение 4
или 8
), в отличие от фактического размера макета (экземпляра) управляемого класса.Это может быть то, что вы хотите, в зависимости от вашей ситуации.Обратите внимание, что результаты такого рода грациозно ухудшаются, объединяя случай структуры, содержащей одну встроенную ссылку (дескриптор) с одной ссылкой (дескриптор).
Более простой способ вызова инструкции sizeof
ILчерез System.Runtime.CompilerServices.Unsafe пакет:
int struct_layout_bytes = Unsafe.Sizeof<T>();
3. Если вам действительно нужен фактический макетРазмер из (экземпляра) управляемого класса по какой-то причине, тогда вы, вероятно, делаете что-то не так, но вы можете получить это с помощью следующего, который работает только для ссылочных типов, то есть, когда typeof(T).IsValueType
false
.
int class_layout_bytes = Marshal.ReadInt32(typeof(T).TypeHandle.Value, 4)
4. Поэтому - и все еще с предыдущим предостережением - чтобы получить размер макета экземпляра для любого типа ссылки или значения, включая те, которые содержат встроенные ссылки, из его ручки Type
объедините методы # 2 и # 3:
int instance_layout_bytes = typeof(T).IsValueType ?
Unsafe.Sizeof<T>() :
Marshal.ReadInt32(typeof(T).TypeHandle.Value, 4);
относящиеся: Размер структуры с полями универсального типа