【问题标题】:.NET Reflection: determine sizes of a class' fields.NET 反射:确定类字段的大小
【发布时间】:2009-07-13 19:41:16
【问题描述】:

目标:以编程方式确定类字段的大小(以字节为单位)。 例如,请参阅下面的 cmets ...

class MyClass
    {
    public  byte    b ;
    public  short   s ;
    public  int i ;
    }

class MainClass
    {
    public static void Main()
        {
        foreach ( FieldInfo fieldInfo
            in typeof(MyClass).GetFields(BindingFlags.Instance
             | BindingFlags.Public | BindingFlags.NonPublic) )
            Console.WriteLine ( fieldInfo.FieldType ) ;

        // output is:
        //    System.Byte
        //    System.Int16
        //    System.Int32

        // desired: to include "sizeof" each type (in bytes) ...
        //    System.Byte     1
        //    System.Int16    2
        //    System.Int32    4
        }
    }

【问题讨论】:

    标签: c# reflection field sizeof


    【解决方案1】:

    您只想在System.Runtime.InteropServices 命名空间中使用Marshal.SizeOf 方法。

    foreach (var fieldInfo in typeof(MyClass).GetFields(BindingFlags.Instance |
        BindingFlags.Public | BindingFlags.NonPublic))
    {
        Console.WriteLine(Marshal.SizeOf(fieldInfo.FieldType));
    }
    

    但请注意备注部分中的以下段落:

    返回的大小是非托管类型的实际大小。对象的非托管和托管大小可以不同。对于字符类型,大小受应用于该类的 CharSet 值影响。

    这些差异可能无关紧要,具体取决于您的目的...我什至不确定是否可以在托管内存中获得确切的大小(或者至少不是没有很大困难)。

    【讨论】:

    • 作为一个不同的例子,sizeof(bool) 是 1 而Marshal.SizeOf(typeof(bool)) 是 4。
    【解决方案2】:

    请注意,字段大小的总和不会是任何给定类实例使用的内存量的总和。 CLR 用于各种目的的对齐填充符和对象标头信息,以及用于监视器支持的可能关联的同步原语(C# 中的lock 关键字)不属于总数的一部分。

    【讨论】:

    • 这绝对正确 - 没有简单的方法(我不确定是否有 any 方法)来获取内存中类的实际大小。但是,我认为 OP 只对各个字段的大小感兴趣。
    • 当然没有完全可移植的方法,最好的方法是基于进程内存和实例数之间的关系进行估计。然而,对于像这样的问题——字段的大小——我通常会以怀疑告终。从一开始就听起来很狡猾...... :)
    • @Barry:是的,确切地说......你正在进入那里的阴暗领域。
    猜你喜欢
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    相关资源
    最近更新 更多