2013-06-06 4 views
11

Wenn Sie eine Struktur deklariert haben:Was macht die Neubildung einer leeren Struktur in C#?

struct EmptyResult 
{ 
} 

Was ist das Ergebnis eine Variable vom Typ EmptyResult in einer Instanz zu schaffen?

Würden Sie eine Zuweisung auf dem Stapel erwarten, oder ist es effektiv ein No-Op?

+0

Ich hoffe, der Compiler optimiert dies. Setzen Sie einen Unterbrechungspunkt auf dieser Linie in Foo und sehen Sie, ob sein Schlag? – Sayse

+0

... – James

+0

Es wäre weg optimiert, wenn Sie die Variable vom Typ 'Int' gemacht haben. Vielleicht würde ein besseres Beispiel die Übergabe der Struktur an eine Funktion beinhalten. –

Antwort

9

Der C# -Compiler zwingt eine leere Struktur zu einer Größe von 1 Byte. Sie können dies sehen, wenn Sie einen Blick auf die Struktur in einem Decompiler haben:

[StructLayout(LayoutKind.Sequential, Size=1)] 
private struct EmptyResult 
{ 
} 

So jede Instanz dieser Struktur in einer Klasse oder auf dem Stapel 1 Byte belegen wird, genau das gleiche wie eine Instanz von System.Byte oder System.SByte

+1

Vermutlich tut es das, um seine Adresse aufnehmen zu können. –

+0

Sie müssen nicht dekompilieren. Sie können 'Marshal.SizeOf (typeof (EmptyResult))' verwenden. Was ich gerade posten wollte, war aber zu langsam. –

+1

@DavidHeffernan Ich bin sicher, du hast recht - es ist so, dass du seine Adresse nehmen kannst, aber auch, damit zwei Instanzen unterschiedliche Adressen haben. Interessanterweise erwähnt [Stroustrup das über leere C++ - Strukturen] (http://www.stroustrup.com/bs_faq2.html#sizeof-empty). –

1

Ich denke, es ist eine Stapelzuweisung, die im Einklang mit Nicht-Referenztypen funktioniert.

+1

Aber die Größe der Struktur ist 0 Bytes; Wie ordnen Sie 0 Bytes zu? – Servy

+0

In C++ nimmt es ein Byte auf. – aquaraga

3

AC# Struktur mit keine Felder hat immer noch eine Größe von 1. Der Grund dafür ist, dass der Compiler in der Lage sein muss, die Adresse einer Struktur mit dem &-Operator in unsicheren Code zu nehmen.

Ich würde erwarten, dass Ihr Strukturtyp genauso behandelt wird wie der byte Typ.

1

Wenn Sie idlasm.exe verwenden il zu studieren, an der Linie, die Sie eine Instanz der Empty Struktur erstellen, werden Sie sehen:

.maxstack 1 
.locals init ([0] valuetype Draft.Empty e) 

und die Definition von Empty Struktur ist:

.class private sequential ansi sealed beforefieldinit Draft.Empty 
     extends [mscorlib]System.ValueType 
{ 
    .pack 0 
    .size 1 
} // end of class Draft.Empty 

Wie Sie sehen, weist es beim Erstellen 1 Byte zu und in der Definition ist die Größe dieses Typs 1.

Also ja; Es weist 1 Byte auf dem Stack zu.

Hinweis: Definition von Empty aus der kompilierten Assembly im Freigabemodus extrahiert.

+0

Die JIT-Stufe könnte es natürlich optimieren –

+0

@DavidHeffernan Ich werde etwas lernen, wenn Sie bitte erklären, wie 'neue Empty(). Entspricht (neue Empty())' True zurückgibt. Braucht es keine tatsächliche Adresse auf dem Stapel? (Ich kenne den JIT-Workflow wirklich nicht); Danke –

+0

'Equals()' prüft Wertgleichheit für Strukturen. Da es keine Felder gibt, ist 's1.Equals (s2)' immer 'wahr' für Operanden vom Typ 'EmptyResult'. –