Was ist der Unterschied zwischen Boxen / Unboxen und Typ Casting?
Oft scheinen die Begriffe synonym verwendet zu werden.
Was ist der Unterschied zwischen Boxen / Unboxen und Typ Casting?
Oft scheinen die Begriffe synonym verwendet zu werden.
Antworten:
Boxing bezieht sich auf eine Konvertierung eines nicht nullbaren Werttyps in einen Referenztyp oder auf die Konvertierung eines Werttyps in eine von ihm implementierte Schnittstelle (z. B. int
zu IComparable<int>
). Ferner ist die Umwandlung eines zugrunde liegenden Werttyps in einen nullbaren Typ auch eine Boxumwandlung. (Vorsichtsmaßnahme: Bei den meisten Diskussionen zu diesem Thema werden die beiden letztgenannten Arten von Konvertierungen ignoriert.)
Zum Beispiel,
int i = 5;
object o = i;
Konvertiert i
in eine Instanz vom Typ object
.
Unboxing bezieht sich auf eine explizite Konvertierung von einer Instanz eines object
oder ValueType
eines nicht nullbaren Werttyps, die Konvertierung eines Schnittstellentyps in einen nicht nullbaren Werttyp (z . B. IComparable<int>
in int
). Ferner ist die Konvertierung eines nullbaren Typs in den zugrunde liegenden Typ auch eine Unboxing-Konvertierung. (Vorsichtsmaßnahme: Bei den meisten Diskussionen zu diesem Thema werden die beiden letztgenannten Arten von Konvertierungen ignoriert.)
Zum Beispiel,
object o = (int)5;
int i = (int)o;
konvertiert die Ganzzahl in o
eine Instanz vom Typ int
.
Eine Typumwandlung ist eine explizite Konvertierung eines Ausdrucks in einen bestimmten Typ. So
(type) expression
Konvertiert explizit expression
in ein Objekt vom Typ type
.
Nullable<T>
Typ. Das Umwandeln eines Werttyps in einen Nullable<T>
(aka T?
) ist KEIN Beispiel für Boxing / Unboxing, da kein Referenztyp erstellt wird. Zum Beispiel int? x = 5
ist ein Beispiel für eine Typbesetzung, NICHT Boxen.
Boxen und Unboxen ist eine Teilmenge der Typbesetzungen. Beim Boxen wird ein Werttyp als Referenztyp behandelt (in der Praxis wird der Inhalt dieses Werttyps (vom Stapel) auf den Heap kopiert und eine Referenz auf dieses Objekt zurückgegeben). Dadurch kann ein Werttyp überall dort übergeben werden, wo ein kompatibler Referenztyp erwartet wird. Außerdem können virtuelle Methodenaufrufe und andere Funktionen von Referenztypen für den Werttyp ausgeführt werden. Das Unboxing ist die Umkehrung dieses Vorgangs (Zurückholen eines Werttyps aus einem Boxed-Objekt).
Typumwandlung ist der Begriff, der für jede Art der Konvertierung von einer Variablen eines bestimmten Typs in eine andere verwendet wird. Es ist ein umfassenderes Konzept.
Vor einigen Minuten habe ich eine verwandte Frage beantwortet, die diesen Unterschied abdeckt . Zusammenfassend habe ich verschiedene Arten von IL-Anweisungen kategorisiert, die vom C # Cast-Operator generiert wurden:
box
IL-Anweisung) und Unboxing ( unbox
IL-Anweisung)dynamic_cast<Type>
in C ++, verwendet castclass
IL-Anweisung zur Überprüfung)static_cast<Type>
in C ++ gibt es viele IL-Anweisungen für verschiedene Arten von Casts zwischen primitiven Typen)op_XXX
Methode).int*
dazu immer noch unveränderlich ist. Und es sind nicht wirklich nur 4 Bytes auf dem Heap. Es enthält Typinformationen und ruft virtuelle Methoden auf: object o = 5; string s = o.ToString();
funktioniert aus diesem Grund. Dies ist unmöglich mit einem einfachen zu tun int*
. In C ++ beinhaltet dies vtables, ... und das Boxen muss auch mit diesem Zeug umgehen.
Boxen ist der Begriff für die Umwandlung eines Werttyps (int, double, float, Guid usw.) in einen Referenztyp (System.Object, System.String usw.). Durch diese Boxoperation wird Speicher auf dem Heap zugewiesen (den der Garbage Collector eventuell zurückfordern muss). Das Unboxing ist die Umkehrung dieses Prozesses, bei dem ein Referenztyp in einen Werttyp umgewandelt wird.
Beim Casting wird ein Typ (z. B. System.Object) als ein anderer Typ (z. B. System.String) behandelt.
Wenn Sie etwas in C # boxen, wandeln Sie es in einen anderen Typ um. Der Unterschied besteht darin, dass beim Erstellen eines neuen Referenztyps zusätzlicher Speicher zugewiesen wird .
Fazit: Boxen ist eine spezielle Art der Besetzung, bei der ein Werttyp in einen Referenztyp konvertiert wird, für den ein neuer Referenztyp zugewiesen werden muss.
IComparable<int> i = 5
führt auch das Boxen. Zweitens boxing
ist dies nicht die einzige Besetzung, die eine Speicherzuweisung erfordert. Benutzerdefinierte Casts können dies ebenfalls tun. Drittens, wie Jason betonte, ist Heap das Implementierungsdetail. Das Wichtigste ist , einen Werttyp nach Referenztypsemantik zu behandeln, nicht dort, wo er zugeordnet ist.
Boxing / Unboxing und Type Casting sind zwei verschiedene Operationen, sie verwenden jedoch dieselbe Syntax.
Sie werden nur synonym verwendet, wenn die Person, die darüber spricht, nicht weiß, was wirklich passiert ...
Beim Boxen wird ein Werttyp als Objekt auf dem Heap gespeichert, und beim Unboxing wird der Wert aus dem Objekt gelesen. Sie können den Wert nur als genauen Typ entpacken.
Casting ist, wenn Sie einen Basistyp in einen anderen Basistyp konvertieren (wie von a int
nach a long
) oder wenn Sie den Typ einer Referenz ändern (wie von List<int>
nach IEnumerable<int>
).
Boxen bedeutet, eine Werttypvariable (dh eine Ganzzahl) in einen Referenztyp umzuwandeln. Unboxing ist das Gegenteil davon, wenn Sie Typ Casting verwenden. In der .NET-Welt leitet sich alles vom Typ "Objekt" ab.
Zum Beispiel (C # Beispiel):
int myInt = 0; // original variable (unboxed to begin with)
object boxed = myInt; // box it up
int myIntUnBoxed = (int)boxed; // and unbox it again using type casting
Dies hat zur Folge, dass das Typensystem vereinheitlicht wird und Werttypen als Referenztypen behandelt werden können. Dieser Artikel befasst sich eingehender mit Boxen / Unboxen.