C# .net对象大小填充?

C# .net对象大小填充?,c#,.net,.net-4.0,clr,C#,.net,.net 4.0,Clr,说 sizeof运算符只能在不安全的代码块中使用。虽然 您可以使用Marshal.SizeOf方法,该方法返回的值 方法并不总是与sizeof返回的值相同 及 Marshal.SizeOf返回封送类型后的大小, 而sizeof返回公用程序分配的大小 语言运行时,包括任何**填充** 有一次我在书中读到:c#via clr(第522页) 即: 问题: 1) 此处提到的填充是否: 与书中提到的相同吗 及 2) 如果我的对象类型为Person,我如何知道它在内存中的真实大小 编辑-为什么我需要它?

sizeof运算符只能在不安全的代码块中使用。虽然 您可以使用Marshal.SizeOf方法,该方法返回的值 方法并不总是与sizeof返回的值相同

Marshal.SizeOf返回封送类型后的大小, 而sizeof返回公用程序分配的大小 语言运行时,包括任何**填充**

有一次我在书中读到:c#via clr(第522页)

即:

问题:

1) 此处提到的填充是否:

与书中提到的相同吗

2) 如果我的对象类型为
Person
,我如何知道它在内存中的真实大小

编辑-为什么我需要它? 请注意:

他们有一个阅读记录样本:

 using (var accessor = mmf.CreateViewAccessor(offset, length))
            {

                int colorSize = Marshal.SizeOf(typeof(MyColor)); //<--------HERE
                MyColor color;


                for (long i = 0; i < length; i += colorSize)
                {
                    accessor.Read(i, out color);
                    color.Brighten(10);
                    accessor.Write(i, ref color);
                }
            }
        }
使用(var accessor=mmf.CreateViewAccessor(偏移量,长度))
{

int colorSize=Marshal.SizeOf(typeof(MyColor));//这可能看起来不真实-但从内存映射文件的角度来看,您感兴趣的大小与内存中该对象的大小不同。它们可能被称为内存映射文件,但在.Net中,这并不一定意味着与本机代码中的大小完全相同。(尽管如此,底层实现仍然是相同的-逻辑内存的一部分映射到文件的一部分,因此名称仍然正确)

sizeof
返回物理内存中对象的正确大小,包括任何填充字节等。因此,如果您需要知道本机内存中对象的确切大小,请使用它(但这不适用于内存映射文件,稍后我将解释)

正如文档所述,
Marshal.SizeOf
从.Net的角度报告对象的大小,不包括两个隐藏的数据项;这两个数据项仅由运行时使用

您复制的示例使用了
Marshal.SizeOf
,因为填充值仅与内存中的物理对象相关。序列化对象时,仅序列化逻辑.Net数据。再次加载对象时,将根据该点的运行时状态重新分配这两个填充值。例如,类型指针可能不同。将它们序列化将毫无意义。这就像将本机指针(而不是偏移量)序列化到磁盘一样-下次指向的数据不太可能位于同一位置


因此,如果你想知道100个
Color
对象的数组在物理内存中使用了多少,请使用
sizeof
;如果你想知道相同数据的memroy映射文件有多大,请使用
marshall.sizeof

,因为如果我使用memorymappedfile,则使用memorymappedfile,并且有一个包含许多记录的文件(个人的),我需要知道偏移长度,所以为什么他们使用
Marshal.SizeOf(typeof(MyColor))
而不是当他们读取memoryMappedFile时的大小?更新了我的答案。将您知道和喜爱的.Net对象视为逻辑数据;实际内存就是物理内存。一般来说,您永远不需要物理内存;甚至在使用内存映射文件时也不需要物理内存,因为在.Net中,您处理的是映射到逻辑数据的文件,而不是物理内存。是的,底层实现确实使用了内存映射文件;但是.Net随后使用它来种子化其他对象。书中的填充问题和msdn中的填充问题是一样的吗?我相信是这样的-我不知道.Net运行时会做任何其他填充。唯一可能的事情可能是单词边界对齐,但这与一个对象在内存中的位置开始,所以我怀疑这是否适用。所以-因为我是通过直接内存访问的-我确实需要大小+填充-因此我使用marshal.sizeOf?