2009-04-18 10 views
27

Eine andere aktuelle C# Interview Frage, die ich hatte, war, wenn ich wusste, was Boxing und Unboxing ist. Ich habe erklärt, dass Werttypen auf Stack und Referenztypen auf Heap sind. Wenn ein Wert in einen Referenztyp umgewandelt wird, nennen wir das Boxen und umgekehrt.Boxen vs Unboxing

Dann fragte er mich, dies zu berechnen:

int i = 20; 
object j = i; 
j = 50; 

Was i ist?

ich messed es auf und sagte: 50, wo sein tatsächlich 20. Nun denke ich, es zu verstehen, warum, aber wenn ich mit verschiedenen Kombinationen spiele ich war überrascht, das zu sehen:

Object a = 1; // Boxing 
Object b = a; // referencing the pointer on stack to both objects on heap 
a = 2; // Boxing 

Ich hatte erwartet, zu siehe auch b == 2, aber es ist nicht, warum? Liegt es daran, dass das zweite Boxing das gesamte a Objekt auf dem Heap zerstört und ersetzt?

Denn wenn ich das tue, es ist in Ordnung:

public class TT 
{ 
    public int x; 
} 

TT t = new TT(); 
t.x = 1; 
TT t2 = new TT(); 
t2.x = 2; 
t = t2; 
t.x = 3; 

Was t2.x ist? Es sollte 3 sein, und es ist. Aber das ist kein Beispiel für Boxen/Unboxing überhaupt, ist das korrekt? Wie würdest du das zusammenfassen?

Konnten die Werte in einer Boxing/Unboxing-Konvertierung wie oben immer gleich sein?

+1

Siehe auch http://stackoverflow.com/questions/13055/what-is-boxing-and-unboxing-and-what-are-the -trade-offs für eine allgemeine Lesung – nawfal

Antwort

5
  1. Sie haben Recht, die zweite Aufgabe ersetzt die erste. Es ändert den Boxed-Wert nicht.

  2. Ihr Beispiel verwendet nicht Boxen. Der Wert (int) wird als int und nicht als Box gespeichert.

  3. Nein, Boxen hält immer noch die Unveränderlichkeitsgarantie.

+0

Hallo, Vielen Dank für Ihre Antwort. Könntest du bitte ein wenig mehr auf "Boxen noch hält die Unveränderlichkeit Garantie."? Dank kave – Houman

+1

meisten Werttypen sind unveränderlich, zum Beispiel: Ein int nur einen Wert haben kann. Wenn Sie den Wert ändern, erstellen Sie im Grunde ein neues int. .NET behält diese Unveränderlichkeit für Box-Objekte bei: Wenn Sie ihm einen neuen Wert zuweisen, erstellen Sie einen neuen Box-Int. Gleiches gilt für Kastenstrukturen. – grover

+0

Macht vollkommen Sinn. Danke – Houman

2

Ich erwartete b == 2 auch zu sehen, ist es aber nicht, warum? ist es, weil das zweite Boxen das ganze (a) -Objekt auf Heap zerstört und ersetzt?

Nein, nicht genau. Es belässt das Objekt so, wie es auf dem Heap ist (wie die Variable b es ebenfalls referenziert) und erstellt ein neues Objekt für den neuen Wert, auf den die Variable a verweist.

Sie haben Recht, dass Ihr zweites Beispiel nicht Boxen verwendet. Sie können nicht auf einen Wert zugreifen, der auf andere Weise eingerahmt ist als durch das Entpacken, sodass es nicht möglich ist, einen eingerahmten Wert zu ändern.

Nicht einmal eine veränderbare Struktur wie Point kann geändert werden, wenn sie umrahmt wird. Um auf die Eigenschaften der Struktur zuzugreifen, müssen Sie sie entpacken, damit Sie die eingerahmte Struktur nicht an Ort und Stelle ändern können.

1

b ist noch 1, weil b ist eine Referenz, die mit einem Wert von 1 einem auf dem Heap auf das Objekt noch Punkte 2, weil Sie es auf ein neues Objekt auf dem Heap mit einem Wert von 2.

zugewiesen

t2.x ist 3, weil t und t2 zwei verschiedene Referenzen auf das gleiche Objekt auf dem Heap sind.

0

Ich denke, die Antwort auf Ihre Frage mit Unboxing ist: Das Ergebnis einer Unboxing-Konvertierung ist eine temporäre Variable (mehr Details: link).

Ich glaube, Sie versuchen, etwas zu tun wie:

object a = new Point(10,10); 
object b = new Point(20,20); 
a = b; 

((Point) b).X = 30; //after this operation also a.X should be 30 

Der obige Code nicht kompiliert werden - Details in dem obigen Link, und ich denke, das ist die Antwort auf Ihre Frage ist:

ich erwarte b == 2 auch zu sehen, ist es aber nicht, warum? ist es, weil das zweite Boxen das ganze (a) -Objekt auf Heap zerstört und ersetzt?

+0

Es ist erwähnenswert, dass es in C++/CLI keine Schwierigkeiten gibt, Boxed-Heap-Objekte direkt in vertrauenswürdigen und nachprüfbaren Code zu ändern. – supercat

8

Sehr kurz: Boxen bedeutet Erstellen einer neuen Instanz eines Referenztyps. Wenn Sie das wissen, verstehen Sie, dass sich eine Instanz nicht ändert, indem Sie eine andere erstellen.

Was Sie mit a = 2 tun, ändert den Wert in der 'Box' nicht, Sie erstellen eine neue Instanz eines Referenztyps. Warum sollte sich sonst etwas ändern?

+1

nette Erklärung, was passiert jetzt, wenn Sie die Box aufheben? Wird die neue Instanz des Referenztyps zerstört? – SoftwareGeek

+1

Referenztypen werden immer durch Garbage Collection zerstört. Es wird also zerstört, wenn es nicht mehr referenziert wird. –

+0

kurze n süße Antwort, wirklich nett – FosterZ

2

Hier ist eine weitere interessante Variante, die Stefan Kommentare unterstützt:

 int i = 2; 
     object a = i; // Boxing 
     object b = a; // Referencing same address on heap as 'a', b == a 

     b = i; // New boxing on heap with reference new address, b != a