使用 C# 获取字段的大小(以字节为单位) [英] Getting the size of a field in bytes with C#

查看:21
本文介绍了使用 C# 获取字段的大小(以字节为单位)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,我想检查它的字段并最终报告每个字段占用的字节数.我假设所有字段都是 Int32、字节等类型.

I have a class, and I want to inspect its fields and report eventually how many bytes each field takes. I assume all fields are of type Int32, byte, etc.

如何轻松找出该字段占用的字节数?

How can I find out easily how many bytes does the field take?

我需要类似的东西:

Int32 a;
// int a_size = a.GetSizeInBytes;
// a_size should be 4

推荐答案

基本上你不能.这将取决于填充,这很可能基于您使用的 CLR 版本和处理器等.假设它没有对其他对象的引用,计算出一个对象的总大小会更容易:创建一个大数组,使用 GC.GetTotalMemory 作为基点,填充包含对您的类型的新实例的引用的数组,然后再次调用 GetTotalMemory.从另一个值中取出一个值,然后除以实例数.您可能应该事先创建一个实例,以确保没有新的 JITted 代码对数字有贡献.是的,它听起来很老套 - 但我以前用过它,效果很好.

You can't, basically. It will depend on padding, which may well be based on the CLR version you're using and the processor etc. It's easier to work out the total size of an object, assuming it has no references to other objects: create a big array, use GC.GetTotalMemory for a base point, fill the array with references to new instances of your type, and then call GetTotalMemory again. Take one value away from the other, and divide by the number of instances. You should probably create a single instance beforehand to make sure that no new JITted code contributes to the number. Yes, it's as hacky as it sounds - but I've used it to good effect before now.

就在昨天,我在想为此编写一个小助手类是个好主意.如果您有兴趣,请告诉我.

Just yesterday I was thinking it would be a good idea to write a little helper class for this. Let me know if you'd be interested.

还有另外两个建议,我想同时解决它们.

There are two other suggestions, and I'd like to address them both.

首先,sizeof 运算符:这仅显示了多少空间类型在抽象中占据,没有在它周围应用填充.(它包括结构内的填充,但不包括应用于另一种类型中该类型变量的填充.)

Firstly, the sizeof operator: this only shows how much space the type takes up in the abstract, with no padding applied round it. (It includes padding within a structure, but not padding applied to a variable of that type within another type.)

接下来,Marshal.SizeOf:这里只显示非托管大小编组后,不是内存中的实际大小.正如文档明确指出的那样:

Next, Marshal.SizeOf: this only shows the unmanaged size after marshalling, not the actual size in memory. As the documentation explicitly states:

返回的大小是实际的非托管类型的大小.这非托管和托管的大小对象可以不同.对于性格类型,大小受应用于该类的 CharSet 值.

The size returned is the actually the size of the unmanaged type. The unmanaged and managed sizes of an object can differ. For character types, the size is affected by the CharSet value applied to that class.

再说一次,填充可以产生影响.

And again, padding can make a difference.

为了澄清我关于填充相关的意思,请考虑以下两个类:

Just to clarify what I mean about padding being relevant, consider these two classes:

class FourBytes { byte a, b, c, d; }
class FiveBytes { byte a, b, c, d, e; }

在我的 x86 机器上,FourBytes 的一个实例占用 12 个字节(包括开销).FiveBytes 的一个实例需要 16 个字节.唯一的区别是e"变量 - 那么它需要 4 个字节吗?嗯,有点……有点不是.很明显,您可以从 FiveBytes 中删除任何单个变量以将大小降低到 12 个字节,但这并不意味着 每个 变量占用 4 个字节(考虑删除所有这些!).单个变量的成本并不是一个在这里很有意义的概念.

On my x86 box, an instance of FourBytes takes 12 bytes (including overhead). An instance of FiveBytes takes 16 bytes. The only difference is the "e" variable - so does that take 4 bytes? Well, sort of... and sort of not. Fairly obviously, you could remove any single variable from FiveBytes to get the size back down to 12 bytes, but that doesn't mean that each of the variables takes up 4 bytes (think about removing all of them!). The cost of a single variable just isn't a concept which makes a lot of sense here.

这篇关于使用 C# 获取字段的大小(以字节为单位)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆