2

我已经看过 Mario Hewardt 的一个会话,其中提到一个包含整数属性的类需要 16 个字节的空间。我想知道一个简单的跟随类的大小如何导致16?

[StructLayout(LayoutKind.Sequential)]
public class MyClass
{
    public int Age;
}

问题是整数占用 4 个字节的空间(对吗?)那么这 12 个其他字节到底是从哪里来的呢?我还使用 Marshal.SizeOf 来获取导致 4 的类大小:

int n = Marshal.SizeOf(typeof(MyClass));
//n == 4

我读过这篇文章,似乎上面的类包含 8 个字节的内部数据(这些数据到底是什么?)、4 个字节的 int 值和 4 个字节的未使用空间。那么如果它需要 16 个字节,为什么 Marshal.SizeOf 返回 4?如果需要 4 个字节,那 8 个字节到哪里去了?我真的很困惑。

4

2 回答 2

2

Marshal.SizeOf(Type)返回等效非托管类型的大小,即如果具有相同的字段布局和打包,等效的非托管类型(例如 C++ 类)将占用多少字节。请注意,此函数仅适用于具有[StructLayout]属性且 LayoutKind 为Explicit或的类Sequential

CLR 在托管堆上分配对象时使用的内存取决于相关 CLR 的内部结构。Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects是一篇关于对象分配的 CLRv2 实现的文章。本质上,每个对象都有两个隐藏字段——一个同步块索引和一个类型句柄。lock(obj) {}同步块是在对象与语句一起使用时使用的内部结构。类型句柄提供关于给定实例的运行时类型信息——它包含对象的方法表等。

于 2012-07-11T06:43:04.200 回答
0

事实上,C# 中的类不仅仅是 id 包含的字段。必须有一个虚函数表,这样你就可以使用 virtual & override 关键字,当然还有其他一些东西,比如可能指向类型元数据的指针......

事实是你不应该关心......重要的是“我需要多少字节才能重建实例?”。答案是 Marshal.SizeOf 给你的:4。

只编组整数的 4 个字节(是的,你是对的,它是 4 个字节),并且知道你想要反序列化一个 MyClass,那么你就有足够的信息来完成它。

于 2012-07-11T06:11:24.443 回答