Ich bin beim Boxen und beim Auspacken etwas verwirrt. Nach seiner Definition
Boxing ist eine implizite Konvertierung von ValueTypes in Reference-Typen (Object).
UnBoxing ist die explizite Konvertierung von Referenztypen (Object) in die entsprechenden ValueTypes.
Das beste Beispiel dafür ist
%Vor%und
%Vor%Aber meine Frage ist, ob int ist Werttyp und String ist Referenztyp so
%Vor%und
%Vor%Ist das ein Beispiel für Boxen und Unboxing oder nicht?
Aufruf von ToString
ist nicht boxend. Es erstellt eine neue Zeichenfolge, die zufälligerweise die textuelle Darstellung Ihres int enthält.
Beim Aufrufen von (object)1
wird eine neue Instanz auf dem Heap erstellt, die ein int enthält. Aber es ist immer noch ein int
. (Sie können dies mit o.GetType()
bestätigen)
String kann nicht mit einem Cast zu int
konvertiert werden. Dein Code wird also nicht kompiliert.
Wenn Sie die Zeichenfolge zuerst in object
umwandeln, wird Ihr Code zwar kompiliert, aber zur Laufzeit nicht ausgeführt, da Ihr Objekt kein Box-Int enthält. Sie können einen Werttyp nur in den genau richtigen Typ (oder die zugehörige Nullwert) auflösen.
Zwei Beispiele:
Gebrochen:
%Vor%Arbeiten:
%Vor% Das ist NICHT Boxen. Dies ist einfach ein Methodenaufruf an Int32.ToString()
, der eine formatierte Zeichenfolge zurückgibt, die den Wert von int
darstellt.
Dieser Code wird nicht kompiliert, da zwischen System.String
und System.Int32
keine explizite Konvertierung definiert ist.
Stellen Sie sich Folgendes vor, um zu verstehen, was
Boxen: Es ist, wenn Sie einen Werttyp nehmen und es einfach in eine Referenzvariable "stecken". Es ist keine typspezifische Konvertierungslogik erforderlich, damit diese Operation funktioniert. Der Variablentyp ist immer noch derselbe, wenn Sie GetType()
verwenden.
Unboxing: Es ist genau die entgegengesetzte Operation. Nehmen Sie einen Werttyp, der in einem Referenzobjekt steckt, und ordnen Sie ihn einer Werttypvariablen zu. Auch hier ist keine typspezifische Konvertierungslogik erforderlich, damit diese Operation funktioniert.
Wenn also (int)s
gültig wäre, wäre es einfach eine explizite Konvertierung und keine Unboxing Operation, weil s.GetType()
System.String
zurückgibt, nicht System.Int32
.
Zu spät zur Party, aber ...... Ich mag es nicht einfach nur Antworten zu lesen und ohne Beweise dahinter. Ich mag es, das Problem zu verstehen und die mögliche Lösung zu analysieren und zu sehen, ob es zu meinem Verständnis passt. Dieser Text zum Kopieren und Einfügen aus der zu Recht hoch gelobten ausgezeichneten 'CLR via C #' des Gottes Jeff Richter erklärt dies:
Auch wenn nicht gebundene Werttypen keinen Typobjektzeiger haben, können Sie weiterhin virtuelle Methoden (wie Equals, GetHashCode oder ToString) aufrufen, die vom Typ geerbt oder überschrieben werden. Wenn Ihr Wertetyp eine dieser virtuellen Methoden überschreibt, kann die CLR die Methode nicht virtuell aufrufen, da Werttypen implizit versiegelt sind und keine davon abgeleiteten Typen haben können. Darüber hinaus ist die Werttypinstanz, die zum Aufrufen der virtuellen Methode verwendet wird, nicht eingerahmt. Wenn Ihre Überschreibung der virtuellen Methode jedoch die Implementierung der Methode des Basistyps aufruft, wird die Werttypinstanz beim Aufrufen der Implementierung des Basistyps eingerahmt, sodass ein Verweis auf ein Heap-Objekt an den this-Zeiger in der Basis übergeben wird Methode. Das Aufrufen einer nichtvirtuellen geerbten Methode (z. B. GetType oder MemberwiseClone) erfordert jedoch immer das Einrahmen des Werttyps, da diese Methoden von System.Object definiert werden. Daher erwarten die Methoden, dass das Argument ein Zeiger ist, der auf ein Objekt verweist Haufen.
Herr Richter sollte eine Medaille für dieses Buch erhalten. Wenn du es nicht hast, hol es !! Dann bekommst du es:)