C# Marshal.SizeOf(typeof(IntPtr))与SizeOf(IntPtr)

C# Marshal.SizeOf(typeof(IntPtr))与SizeOf(IntPtr),c#,.net,C#,.net,我知道Marshal.SizeOf()和SizeOf()有多么根本不同。但是在IntPtr的情况下,它们不总是返回完全相同的东西,而不管CPU架构如何吗?首先,你为什么想知道?如果您的代码编写得很好,您应该不需要对返回的sizeof和Marshal.sizeof进行任何假设。您是否将使用封送处理程序封送任何IntPtr实例?然后使用Marshal.SizeOf。您的变量是否从未离开托管世界,或者您是否正在使用自定义编组?然后使用sizeof(或者IntPtr.Size,因为它不需要safe块)。

我知道
Marshal.SizeOf()
SizeOf()
有多么根本不同。但是在
IntPtr
的情况下,它们不总是返回完全相同的东西,而不管CPU架构如何吗?

首先,你为什么想知道?如果您的代码编写得很好,您应该不需要对返回的
sizeof
Marshal.sizeof
进行任何假设。您是否将使用封送处理程序封送任何
IntPtr
实例?然后使用
Marshal.SizeOf
。您的变量是否从未离开托管世界,或者您是否正在使用自定义编组?然后使用
sizeof
(或者
IntPtr.Size
,因为它不需要
safe
块)。在这两种情况下,您都不会关心它们是否返回相同的值。这是实际的答案

关于这个理论。根据,为
sizeof(IntPtr)
返回的值是“该类型变量中的总字节数,包括任何填充”(因为
IntPtr
是一种结构)。然而,它也注意到这个值是“实现定义的”。因此,如果你想了解技术,C#规范只是简单地说“弄明白”

这就是说,
IntPtr
的文档清楚地表明,该类型在32位平台上是32位的,在64位平台上是64位的,而
IntPtr
是一种特殊的内置类型,对应于
本机int
,因此我想我们可以暂时得出
sizeof(IntPtr)的结论
在声称遵循规范的任何实现上都是可预测的:32位平台上4个,64位平台上8个
IntPtr.Size
是另一种选择,它明确地记录了这一点

Marshal.SizeOf(typeof(IntPtr))
是另一个beast。除了“非托管类型的大小”之外,它没有确切记录它将返回的内容;在水下,它调用CLR中的一些本机代码,询问
TypeHelper
底层类型的大小。对于<代码> ItpTrt/Cuff>,这将返回<代码> SigeOf(Value*)<代码>(C++),当然,在32位平台上,4位是在64位平台上,对于绝大多数C++编译器和平台来说是这样的。
从技术上讲,理论上讲,
sizeof(IntPtr)
Marshal.sizeof(typeof(IntPtr))
可能不同。但一般来说,您不必担心这一点,因为运行时和jitter(或AOT编译器)的结合不能使
sizeof(IntPtr)
等于
Marshal.sizeof(typeof(IntPtr))
——否则运行时只会让自己的生活变得更加困难。另一方面,正如我所指出的,通常也没有任何理由认为它们是相同的。

首先,有基本类型:

| x64 | x86

|封送官。|元帅
原语| SizeOf()SizeOf(T)| SizeOf()SizeOf(T)

======================================================================

Boolean | 4 1 | 4 1

Byte|11 | 11

SByte | 11 | 11

Int16 | 22 | 22

UInt16 | 2 | 2

Int32 | 4 | 4

UInt32 | 4 | 4

Int64 | 8 | 8

UInt64 | 8 | 8

IntPtr|8 4

uintpttr | 8 4

Char | 12 | 12

Double | 8 8 | 8 8

单曲| 4 | 4

除此之外,对于.NET中的struct(
ValueType
)实例,内部托管布局和封送映像在总大小和字段布局顺序上可能存在显著差异。后者即使是所谓的

实际上很少需要关于实际托管结构布局的信息,事实上,.NET竭尽全力使其不可发现。您也不能影响结构的内部布局,这正是
封送处理
层提供专门声明互操作所需布局的能力的原因

这里有一个需要知道结构的运行时内存映像的真实大小的用例:假设您使用结构的托管数组来实现某种类型的存储blob概念,并且希望每个块(即数组)保持在固定的总分配大小之下,例如~84800字节——在本例中,显然不在内存中。您希望此存储类是一个泛型类,用定义“记录”或表项的任意
ValueType
类型参数化。要确定可以进入每个托管数组块的结构的数量,您需要发现在运行时给定的结构的真实大小,以便将84800除以该值

有关封送托管内部结构布局、填充和大小之间可能出现的差异的更详细的检查,请参阅我对“”的扩展回答