2016-03-12 10 views
5

Ich versuche, die Größe aller meiner Variablen (Werttypen) mit sizeof-Operator zu überprüfen. Ich durch eine der msdn article gegangen, wo es steht geschrieben, dasssizeof-Operator gibt zusätzliche Größe einer Struktur in C#

Für alle anderen Typen, einschließlich structs kann der Operator sizeof nur in unsicheren Code-Blöcke

und auch structs enthalten sollte nicht verwendet werden, Felder oder Eigenschaften, die

Für diese Referenztypen sind, aktivierten die ich in meinen Projekteigenschaften unsicher Zusammenstellung und erstellte Struktur als folgt-

struct EmployeeStruct 
{ 
    int empId; 
    long salary;  
} 

und verwendet es als folgt-

unsafe 
{ 
    size = sizeof(EmployeeStruct); 
} 

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

Hier bin ich als Ausgangsgröße des Typs in Bytes bekommt: 16 aber an Struktur, indem man sollte es 12 (4 für int und 8 für lang) sein. Kann jemand mir helfen, hier zu verstehen, warum ich 4 Byte zusätzliche Größe bekomme?

+0

Der Link, den Sie gaben, sagt Ihnen: "while sizeof gibt die Größe zurück, wie sie von der Common Language Runtime zugewiesen wurde, ** inklusive Padding **" – DavidG

+0

@EugenePodskal Es ändert sich viel - Leute, die Antworten suchen Ein Problem bei C# wird keine Fragen zu C aufwerfen, sie sind sehr unterschiedliche Sprachen, auch wenn die Antwort dieselbe ist. –

+0

@GediminasMasaitis Dann werden sie diese Frage finden und das Duplikat lesen (naja, zumindest sollten sie). Aber wenn Sie denken, dass es sich lohnt, können Sie eine korrekte kanonische C# -spezifische Antwort schreiben. In diesem Fall würde ich Ihnen auch empfehlen, die Frage in leichter durchsuchbare und auf den Punkt bezogene "sizeof returns value, die größer als erwartet ist" oder etwas in dieser Zeile umzubenennen. –

Antwort

1

Sie müssen keinen unsicheren Code verwenden. Es wird empfohlen, System.Runtime.InteropServices.Marshal.SizeOf()

zu verwenden zB: Marshal.SizeOf (new EmployeeStruct());

, dass 16 statt 12 zurückkehren, da die Standard-Packmaß im Speicher 8.

Also, für:

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

// zurückkehren 16 statt 12 (weil de min Einheit ist 8)

für:

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

// 16 Rückkehr zu

und für

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

Rückkehr 24 statt 20 (weil de min Einheit 8)

Ich weiß nicht, was Sie wollen, aber wenn man die Summe der einzelnen Felder Größe benötigen, können Sie versuchen, mit dieser Funktion:

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; 
    } 

es gibt 12 statt 16, für Ihren Fall, und Sie können es für komplexe Strukturen verwendet werden, zB:

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) wird 24 statt 32 zurückgeben, aber denken Sie daran, die REAL SIZE ON MEMORY ist 32, der Compiler verwendet 32 ​​Bytes, um Speicher zuzuweisen.

Grüße.

+0

Aber warum hat eine Struktur mit drei "int" eine Größe von 12 und nicht 16? –

+0

Thnx Gonzalo. Aber ist das nicht wahr, dass System.Runtime.InteropServices.Marshal.SizeOf die nicht verwaltete zugewiesene Größe nach dem Marshelling zurückgibt? Haben wir keine Möglichkeit, die korrekte Größe der verwalteten oder CLR-Größe zu ermitteln? –

+0

Ich habe meine Antwort bearbeitet, vielleicht kann ich dir helfen. Grüße. – Gonzalo