sizeof运算符在C#中给出了结构的额外大小

时间:2016-03-12 16:34:04

标签: c# struct sizeof

我正在尝试使用sizeof运算符检查所有变量(值类型)的大小。我经历了msdn article中写有

之一的地方
  

对于所有其他类型,包括结构,sizeof运算符只能用于不安全的代码块

并且结构不应包含任何引用类型的字段或属性

为此,我在项目属性中启用了不安全的编译,并按如下方式创建了结构 -

struct EmployeeStruct
{
    int empId;
    long salary;       
}

并按如下方式使用 -

unsafe
{
   size = sizeof(EmployeeStruct);
}

Console.WriteLine("Size of type in bytes is: {0}", size);

这里我得到输出,因为字体大小是16:但是通过查看结构它应该是12(4表示int,8表示长)。 有人可以帮我理解为什么我得到4字节的额外大小?

1 个答案:

答案 0 :(得分:1)

您不需要使用不安全的代码。建议使用System.Runtime.InteropServices.Marshal.SizeOf()

例如:Marshal.SizeOf(new EmployeeStruct());

返回16而不是12,因为内存中的默认包大小为8。

所以,对于:

struct EmployeeStruct
{
    int empId; // 4 bytes
    long salary;  8 bytes
}

//返回16而不是12(因为de min单位是8)

有:

 struct EmployeeStruct
 {
    int empId; // 4 bytes
    int empAge; // 4 bytes
    long salary;  8 bytes
  }

//也返回16

   struct EmployeeStruct
   {
      int empId; // 4 bytes
      int empAge; // 4 bytes
      int IdCompany; // 4 bytes
      long salary;  8 bytes
   }

返回24而不是20(因为de min单位是8)

我不知道你想要什么,但如果你需要每个字段大小的总和,你可以试试这个功能:

    public int SizeOf(Type t)
    {
        int s = 0;
        var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
        foreach (var f in fields)
        {
            var x = f.FieldType;
            s += x.IsPrimitive ? Marshal.SizeOf(x) : SizeOf(x);
        }

        return s;
    }

对于您的情况,它返回12而不是16,您可以将它用于复杂结构,例如:

    struct EmployeeStruct
    {
        int field1; // 4 bytes
        long field2; // 8 bytes
        Person p; // 12 bytes
    }

    struct Person
    {
        int field1; // 4 bytes
        long field2; // 8 bytes
    }  

SizeOf(typeof(EmployeeStruct)将返回24而不是32,但请记住,REAL SIZE ON MEMORY是32,编译器使用32个字节来分配内存。

问候。