所有在C#中的默認struct
都被視爲[StructLayout(LayoutKind.Sequential)]
- 標記值類型。所以,讓我們的struct
小號一些數量,並檢查該struct
S的尺寸:CLR順序結構佈局:對齊和大小
using System;
using System.Reflection;
using System.Linq;
using System.Runtime.InteropServices;
class Foo
{
struct E { }
struct S0 { byte a; }
struct S1 { byte a; byte b; }
struct S2 { byte a; byte b; byte c; }
struct S3 { byte a; int b; }
struct S4 { int a; byte b; }
struct S5 { byte a; byte b; int c; }
struct S6 { byte a; int b; byte c; }
struct S7 { int a; byte b; int c; }
struct S8 { byte a; short b; int c; }
struct S9 { short a; byte b; int c; }
struct S10 { long a; byte b; }
struct S11 { byte a; long b; }
struct S12 { byte a; byte b; short c; short d; long e; }
struct S13 { E a; E b; }
struct S14 { E a; E b; int c; }
struct S15 { byte a; byte b; byte c; byte d; byte e; }
struct S16 { S15 b; byte c; }
struct S17 { long a; S15 b; }
struct S18 { long a; S15 b; S15 c; }
struct S19 { long a; S15 b; S15 c; E d; short e; }
struct S20 { long a; S15 b; S15 c; short d; E e; }
static void Main()
{
Console.WriteLine("name: contents => size\n");
foreach (var type in typeof(Foo).GetNestedTypes(BindingFlags.NonPublic))
{
var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine("{0}: {2} => {1}", type.Name, Marshal.SizeOf(type),
string.Join("+", fields.Select(_ => Marshal.SizeOf(_.FieldType))));
}
}
}
輸出是(在x86/x64的相同):
name: contents => size
E: => 1
S0: 1 => 1
S1: 1+1 => 2
S2: 1+1+1 => 3
S3: 1+4 => 8
S4: 4+1 => 8
S5: 1+1+4 => 8
S6: 1+4+1 => 12
S7: 4+1+4 => 12
S8: 1+2+4 => 8
S9: 2+1+4 => 8
S10: 8+1 => 16
S11: 1+8 => 16
S12: 1+1+2+2+8 => 16
S13: 1+1 => 2
S14: 1+1+4 => 8
S15: 1+1+1+1+1 => 5
S16: 5+1 => 6
S17: 8+5 => 16
S18: 8+5+5 => 24
S19: 8+5+5+1+2 => 24
S20: 8+5+5+2+1 => 24
望着這導致我無法理解規則集CLR用於順序結構的佈局(字段對齊和總大小)。有人可以解釋我這種行爲嗎?
您是否要求CLR用於託管空間中的結構(這是一個實現細節)的規則集,或者在託管非託管空間之間編組結構時由編組人員使用的規則集(Marshal.SizeOf返回結構體的大小在編組後,而不是管理空間中的結構)? – dtb
將其縮小一點,哪些特定結果出乎意料? –
@dtb順序佈局這兩件事情是完全一樣的。 Marshal.SizeOf()提供完全相同的大小,因爲C#的sizeof運算符返回。 – ControlFlow