In Bezug auf Casting generic type " als T ", während die Art von T erzwingen
Und mit dem folgenden Beispiel
%Vor%und
%Vor% Ich bin es gewohnt, das object as Type
Casting zu machen, also war ich etwas verwirrt, als ich herausfand, dass ich das nicht mit T
machen konnte. Dann habe ich die obige Frage und damit eine Lösung für den as T
Compilerfehler gefunden.
Aber warum ist where T : class
notwendig, wenn object as T
verwendet wird und nicht wenn (T)object
verwendet wird?
Was ist der tatsächliche Unterschied zwischen den beiden Arten, das Objekt zu werfen?
Weil as
impliziert, dass die Umwandlung fehlschlagen kann und null zurückgibt . Ohne ein : class
könnte T
int
etc sein - was nicht null
sein kann. Mit (T)obj
explodiert es einfach in einem Funkenregen; Keine Notwendigkeit, ein null
zu behandeln.
Als Nebenbemerkung (re struct
) vermerken Sie, dass as
verwenden kann, wenn bekannt ist, dass Sie auf eine Nullable<>
umwandeln - zum Beispiel:
Casting mit "as" ist auf 1) festgelegt, wenn dies möglich ist, und 2) gibt null
zurück, wenn dies nicht möglich ist. Dies ist problematisch mit einem unbeschränkten generischen Parameter (Ihr zweites Beispiel), weil T möglicherweise ein Werttyp sein könnte (wie int
), deren Variablen null
nicht enthalten können.
Wenn Ihr generischer Parameter auf einen Referenztyp beschränkt ist (mit der Einschränkung class
), kann der Compiler Ihren Typ etwas genauer betrachten und verstehen, dass null
immer ein gültiger Wert für den Typ T ist. Deshalb , die "As" -Stil-Besetzung kann sicher verwendet werden.
Soweit der Operator as
im Fehlerfall null
zurückgibt, sollte die Variable eine Klasse oder eine nullbare Struktur sein:
Inzwischen erfordert cast
nichts dergleichen und Sie können struct in struct konvertieren.
(T)obj
wirft, wenn obj
nicht in T
konvertierbar ist. Sie sollten (T)obj
verwenden, wenn Sie sicher sind, dass die Konvertierung funktioniert.
Und verwenden Sie as
, um einen Test durch is
gefolgt von einem Cast zu ersetzen. Natürlich muss T nullfähig sein (entweder ein Referenztyp oder ein Nullable<T>
), da as
bei einem Fehler null zurückgibt. Das typische Muster ist:
Ein weiterer Unterschied ist, dass as
nur für eine Teilmenge von Conversions funktioniert. Überladene Umwandlungen usw. werden ignoriert.