Tutti gli struct
s in C# sono considerati come valori di tipo con segno [StructLayout(LayoutKind.Sequential)]
. Quindi, consente di prendere un po 'numero di struct
s e controllare le dimensioni di questo struct
s:Layout sequenziale delle strutture CLR: allineamento e dimensioni
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))));
}
}
}
uscita è (lo stesso su 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
Guardando questo si traduce non riesco a capire il layout (allineamento dei campi e dimensione totale) set di regole CLR utilizzato per le strutture sequenziali. Qualcuno può spiegarmi questo comportamento?
Si sta richiedendo il set di regole utilizzato dal CLR per le strutture nello spazio gestito (che è un dettaglio di implementazione) o il set di regole utilizzato dal gestore di marshalling durante il marshalling delle strutture tra uno spazio gestito non gestito (Marshal.SizeOf restituisce la dimensione di una struttura dopo il marshalling, non della struttura nello spazio gestito)? – dtb
Riducetelo un po ', quali risultati particolari sono inaspettati? –
@dtb con layout sequenziale queste due cose sono completamente uguali. 'Marshal.SizeOf()' fornisce completamente le stesse dimensioni, come restituisce l'operatore C# 'sizeof'. – ControlFlow