Unterschied zwischen DirectCast () und CType () in VB.NET

99

Ich bin ein erfahrener C / C ++ / C # -Programmierer, der gerade in VB.NET eingestiegen ist. Im Allgemeinen verwende ich CType (und CInt, CBool, CStr) für Casts, da es weniger Zeichen enthält und die erste Art des Castings war, der ich ausgesetzt war, aber ich kenne auch DirectCast und TryCast.

Gibt es einfach Unterschiede (Auswirkung von Besetzung, Leistung usw.) zwischen DirectCast und CType? Ich verstehe die Idee von TryCast.

Caleb Herd
quelle
6
Exaktes Duplikat dieser Casting-Datentypen mit DirectCast, CType, TryCast stackoverflow.com/questions/2703585/…
MarkJ
1
Mögliches Duplikat von Casting DataTypes mit DirectCast, CType, TryCast
Imad

Antworten:

182

Das erste, was zu beachten ist, ist, dass VB.NET kein direktes Analogon zum (type)instanceCasting-Mechanismus von C # hat . Ich spreche dies an, weil es als Ausgangspunkt für den Vergleich der beiden VB.NET-Operatoren nützlich ist (und sie sind Operatoren, keine Funktionen, obwohl sie eine Funktionssemantik haben).

DirectCast()ist strenger als der C # Casting-Operator. Sie können nur wirken, wenn der Gegenstand, auf den bereits gewirkt wird, der Typ ist, auf den Sie wirken. Ich glaube, es werden immer noch Werttypen entpackt, aber sonst wird keine Konvertierung durchgeführt. So können Sie beispielsweise nicht wie bei einem C # -Guss von shortbis umwandeln. Sie können jedoch von einem in ein Array umwandeln, wenn Ihre zugrunde liegende Objektvariable wirklich eine ist . Und natürlich können Sie von in alles umwandeln, vorausgesetzt, der Typ Ihrer Objektinstanz liegt tatsächlich irgendwo unter Ihrem Umwandlungstyp im Vererbungsbaum.int(int)IEnumerableIEnumerableArrayObject

Dies ist wünschenswert, weil es viel schneller ist . Es müssen weniger Konvertierungs- und Typprüfungen durchgeführt werden.

CType()ist weniger streng als der C # Casting-Operator. Es wird Dinge tun, die Sie mit einer einfachen (int)Besetzung einfach nicht tun können , wie das Konvertieren einer Zeichenfolge in eine Ganzzahl. Es hat so viel Kraft wie das Aufrufen Convert.To___()von C #, wobei das ___der Zieltyp Ihrer Besetzung ist.

Dies ist wünschenswert, weil es sehr mächtig ist. Diese Leistung geht jedoch zu Lasten der Leistung. Es ist nicht so schnell wie der DirectCast()Cast-Operator von oder C #, da es möglicherweise ziemlich viel Arbeit erfordert, um den Cast zu beenden. Im Allgemeinen sollten Sie es vorziehen, DirectCast()wenn Sie können.

Schließlich haben Sie einen Casting-Operator verpasst:: Dies TryCast()ist ein direktes Analogon zum asOperator von C # .

Joel Coehoorn
quelle
23
+1 Ich würde sagen, die Strenge von DirectCastist ein weiterer Vorteil. Wenn Sie einen Fehler machen, werden Sie vom Compiler sofort benachrichtigt. Bei CTypeeinem Fehler kann es jedoch gelegentlich zu einem falschen Verhalten zur Laufzeit kommen - möglicherweise auf einem Benutzercomputer mit unterschiedlichen regionalen Einstellungen.
MarkJ
1
Gute Antwort. Also, um die Komplexität (klein bis groß): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()wäre richtig?
Motto
3
@motto - schließen. Die "Funktionen" von C <xyz> () sollten in der Liste weiter oben verschoben werden, da sie tatsächlich eher Operatoren als Funktionen sind, obwohl sie eine Funktionssemantik haben. Für diejenigen Typen, die sie haben, sind sie dem Casting von C # (Typ) sehr nahe, erledigen aber nur ein wenig mehr Arbeit.
Joel Coehoorn
3
@MarkJ +1 für Ihren Kommentar, aber Hinweis DirectCastgilt nur für Klassen, nicht für Schnittstellen (da Sie COM-Typen haben können - und möglicherweise auch andere -, die tatsächlich Schnittstellen implementieren, die nicht in der .GetInterfacesListe des .NET-Typs definiert sind ).
Mark Hurd
2
@ JoelCoehoorn +1, aber eigentlich TryCast()und assind nicht genau gleich. TryCast()Funktioniert nur mit Referenztypen, während asalles funktioniert, was null sein kann. Funktioniert also int? icast = myNum as int?;einwandfrei, gibt aber Dim icast as Integer? = TryCast(myNum, Integer?)einen Compilerfehler aus. Nur noch ein merkwürdiger Unterschied zwischen den beiden Sprachen. lol
CptRobby
12

Mit CTypekann man so etwas schreiben Ctype("string",Integer). Aber mit DirectCastder obigen Anweisung würde Kompilierungszeitfehler geben.

 Dim a As Integer = DirectCast("1", Integer) 'Gives compiler error
 Dim b As Integer = CType("1", Integer) 'Will compile
Abhay
quelle
0

DirectCastist restriktiver als CType.

Dies löst beispielsweise einen Fehler aus:

Sub Main()
    Dim newint As Integer = DirectCast(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub

Es wird auch in der Visual Studio-IDE angezeigt.

Dies wirft jedoch keinen Fehler aus:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
Hemantha
quelle