Es fällt mir schwer, das zu verstehen. Betrachten Sie das folgende Beispiel:
%Vor% Der spezifische Fehler, den ich zur Laufzeit bekomme, ist Specified cast is not valid.
Wenn ich QuickWatch (int)thirdTest
in Visual Studio bekomme, bekomme ich einen Wert von Cannot unbox 'thirdTest' as a 'int'
.
Was zum Teufel geht hier vor?
Unboxing prüft den genauen Typ, wie in der Dokumentation erläutert.
Unboxing ist eine explizite Konvertierung vom Typ Objekt in einen Wert Geben Sie oder von einem Schnittstellentyp zu einem Werttyp, der die implementiert Schnittstelle. Eine Unboxing-Operation besteht aus:
Überprüfung der Objektinstanz, um sicherzustellen, dass es sich um einen Boxed-Wert von handelt der angegebene Werttyp.
Kopieren des Werts von der Instanz in die value-type-Variable.
Wie Sie sehen, ist der erste Schritt, zu überprüfen, ob die Objektinstanz mit dem Zieltyp übereinstimmt.
Zitieren Sie auch aus der Dokumentation:
Damit das Auspacken von Wertetypen zur Laufzeit erfolgreich ist, ist das Element Unboxed muss eine Referenz auf ein Objekt sein, das zuvor erstellt wurde indem Sie eine Instanz dieses Werttyps einbetten. Versuch, NULL zu entfernen verursacht eine NullReferenceException. Versuch, einen Verweis auf einen Inkompatibler Werttyp verursacht eine InvalidCastException.
Um diesen Fehler zu beheben, vergewissern Sie sich, dass der Typ übereinstimmt, bevor Sie versuchen, die Ausgabe aufzuheben:
%Vor%Was hier vor sich geht, ist genau das, was es sagt.
Im ersten Fall haben Sie eine kurze, nicht boxed, die Sie dann explizit zu einem int typisieren. Dies ist eine gültige Konvertierung, die der Compiler zu tun weiß, also funktioniert es.
Im zweiten Fall haben Sie ein int, boxed, das einem int zugeordnet wird. Dies ist ein einfaches Unboxing einer ganzen Zahl, das auch gültig ist, also funktioniert es.
Im dritten Fall haben Sie eine kurze Box, die Sie in eine Variable auspacken möchten, die keine Abkürzung ist. Dies ist keine gültige Operation: Sie können dies nicht in einem Schritt tun. Dies ist auch kein ungewöhnliches Problem: Wenn Sie beispielsweise SqlDataReader
verwenden, das eine SMALLINT
-Spalte enthält, können Sie Folgendes nicht tun:
In Ihrem dritten Beispiel sollte einer der folgenden Punkte funktionieren:
%Vor% Int16
ist eine fantastische Möglichkeit, short
zu schreiben; Dort gibt es kein Boxing / Unboxing, nur die einfache CLR-Konvertierung zwischen 16-Bit- und 32-Bit-Ganzzahlen.
Im zweiten Fall wird der gleiche Typ aktiviert und derselbe Typ wird freigegeben. Der Werttyp int
wird in ein object
eingeschlossen und dann ausgepackt.
Der dritte Fall versucht, zu einem anderen -Typ ( int
anstelle von short
) aufzulösen, was nicht erlaubt ist.