在.NET struct design guidelines中,它将结构的最大合理大小赋予16个字节。如何确定结构的大小,是否受程序运行架构的影响?这个值是32位还是两个拱?
答案 0 :(得分:7)
这不是一个强硬的价值 - 它只是一个指导方针,一个经验法则。根据确切的情况,24或甚至32个字节仍然可以完全合理 - 但如果你的结构变得那么大,那么你应该首先问问自己它是否适合作为结构。它可能是 - 在这种情况下,在执行赋值或将参数传递给方法(等)的任何时候复制那些32字节的命中可能是正确的做法;在其他情况下,你应该真正使用一个类。
至于如何确定结构的大小 - 通常它是相当明显的,因为通常值类型只包含其他值类型。如果您的结构包含引用(或IntPtr
/ UIntPtr
),则更多的是问题 - 但这种情况非常罕见。 (正如Mehrdad所指出的那样,为了对齐,还存在填充问题。)
然后,我发现无论如何我想写自己的结构是非常罕见的。你的情况怎么样?
答案 1 :(得分:4)
在.Net中,大多数类型不会在32位和64位程序之间改变大小。框架定义的唯一两种值类型将根据平台更改其大小
除非您的结构中直接或间接拥有其中一个,否则不应更改平台之间的大小。
正如Mehrdad指出的那样,其他两类将根据平台改变大小的字段是
所有这些类型虽然会以完全相同的方式改变。 32位平台上有4个字节,64位平台上有8个字节。
答案 2 :(得分:3)
是的,结构的大小受体系结构的影响。 32位的C#结构在4字节边界处对齐,在64位中它们是8字节对齐的。
示例:
struct Foo
{
int bar;
}
这个结构的实例在32位进程中占用4个字节,在64位进程中占用8个字节,即使“int bar”在32位和64位进程上只占用4个字节。
<强>更新强>
我做了一些测试。我写了这段代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
struct Bar
{
int a;
}
struct Foo
{
Uri uri;
int a;
}
class Program
{
static void Main(string[] args)
{
Foo[] foo;
long fooBefore = System.GC.GetTotalMemory(true);
foo = new Foo[10];
long fooAfter = System.GC.GetTotalMemory(true);
Bar[] bar;
long barBefore = System.GC.GetTotalMemory(true);
bar = new Bar[10];
long barAfter = System.GC.GetTotalMemory(true);
Foo aFoo = new Foo();
Bar aBar = new Bar();
System.Console.Out.WriteLine(String.Format("[Foo] Size of array of 10: {0}, Marshal size of one: {1}", fooAfter - fooBefore, System.Runtime.InteropServices.Marshal.SizeOf(aFoo)));
System.Console.Out.WriteLine(String.Format("[Bar] Size of array of 10: {0}, Marshal size of one: {1}", barAfter - barBefore, System.Runtime.InteropServices.Marshal.SizeOf(aBar)));
System.Console.ReadKey();
}
}
}
作为一个64位进程,我得到了这个输出:
[Foo] Size of array of 10: 208, Marshal size of one: 16
[Bar] Size of array of 10: 88, Marshal size of one: 4
作为一个32位进程,我得到了这个输出:
[Foo] Size of array of 10: 92, Marshal size of one: 8
[Bar] Size of array of 10: 64, Marshal size of one: 4
观察: