Casting ist das Prozess zum Konvertieren eines Datentyps in einen anderen, beispielsweise von einem Integer-Typ in einen String-Typ. Einige Operationen in VB.NET erfordern bestimmte Datentypen, um zu funktionieren. Casting erstellt den Typ, den Sie benötigen. Der erste Artikel in dieser zweiteiligen Reihe, Casting und Datentypkonvertierungen in VB.NET, führt in das Casting ein. Dieser Artikel beschreibt die drei Operatoren, die Sie zum Einfügen verwenden können VB.NET - DirectCast, CType und TryCast - und vergleicht deren Leistung.
Die Leistung ist laut Microsoft und anderen Artikeln einer der großen Unterschiede zwischen den drei Casting-Betreibern. Beispielsweise warnt Microsoft normalerweise davor, dass "DirectCast... kann eine etwas bessere Leistung als CType bieten beim Konvertieren zum und vom Datentyp Objekt." (Betonung hinzugefügt.)
Ich beschloss, einen Code zu schreiben, um ihn zu überprüfen.
Aber zuerst ein Wort der Vorsicht. Dan Appleman, einer der Gründer des Fachbuchverlags Apress und ein zuverlässiger Techniker Guru, sagte mir einmal, dass es viel schwieriger ist, Benchmarking-Leistung richtig zu machen als die meisten Menschen realisieren. Es gibt Faktoren wie die Maschinenleistung, andere Prozesse, die möglicherweise parallel ausgeführt werden, die Optimierung wie Speicher-Caching oder Compiler-Optimierung und Fehler in Ihren Annahmen darüber, was der Code tatsächlich ist tun. In diesen Benchmarks habe ich versucht, Vergleichsfehler von "Äpfeln und Orangen" zu beseitigen, und alle Tests wurden mit dem Release-Build ausgeführt. Diese Ergebnisse können jedoch immer noch fehlerhaft sein. Wenn Sie etwas bemerken, lassen Sie es mich bitte wissen.
Die drei Casting-Operatoren sind:
- DirectCast
- CType
- TryCast
In der Praxis werden Sie normalerweise feststellen, dass die Anforderungen Ihrer Anwendung bestimmen, welchen Operator Sie verwenden. DirectCast und TryCast haben sehr enge Anforderungen. Wenn Sie DirectCast verwenden, muss der Typ bereits bekannt sein. Obwohl der Code ...
theString = DirectCast (theObject, String)
... Wird erfolgreich kompiliert, wenn theObject noch keine Zeichenfolge ist, löst der Code eine Laufzeitausnahme aus.
TryCast ist noch restriktiver, da es bei "Wert" -Typen wie Integer überhaupt nicht funktioniert. (String ist ein Referenztyp. Weitere Informationen zu Werttypen und Referenztypen finden Sie im ersten Artikel dieser Reihe.) Dieser Code ...
theInteger = TryCast (theObject, Integer)
... wird nicht einmal kompilieren.
TryCast ist nützlich, wenn Sie nicht sicher sind, mit welchem Objekttyp Sie arbeiten. Anstatt einen Fehler wie DirectCast auszulösen, gibt TryCast nur Nothing zurück. Normalerweise wird nach der Ausführung von TryCast auf Nothing getestet.
Nur CType (und die anderen "Convert" -Operatoren wie CInt und CBool) konvertieren Typen, die keine Vererbungsbeziehung haben, wie z. B. eine Ganzzahl, in einen String:
Dim theString As String = "1" Dim theInteger As Integer. theInteger = CType (theString, Integer)
Dies funktioniert, weil CType "Hilfsfunktionen" verwendet, die nicht Teil der .NET CLR (Common Language Runtime) sind, um diese Konvertierungen durchzuführen.
Denken Sie jedoch daran, dass CType auch eine Ausnahme auslöst, wenn theString nichts enthält, das in eine Ganzzahl konvertiert werden kann. Wenn die Möglichkeit besteht, dass die Zeichenfolge keine solche Ganzzahl ist ...
Dim theString As String = "George"
... dann funktioniert kein Casting-Operator. Selbst TryCast funktioniert nicht mit Integer, da es sich um einen Werttyp handelt. In einem solchen Fall müssten Sie die Gültigkeitsprüfung wie den TypeOf-Operator verwenden, um Ihre Daten zu überprüfen, bevor Sie versuchen, sie umzuwandeln.
In der Microsoft-Dokumentation für DirectCast wird speziell das Casting mit einem Objekttyp erwähnt, sodass ich dies in meinem ersten Leistungstest verwendet habe. Das Testen beginnt auf der nächsten Seite!
DirectCast verwendet normalerweise einen Objekttyp, daher habe ich diesen in meinem ersten Leistungstest verwendet. Um TryCast in den Test aufzunehmen, habe ich auch einen If-Block eingefügt, da fast alle Programme, die TryCast verwenden, einen haben. In diesem Fall wird es jedoch niemals ausgeführt.
Hier ist der Code, der alle drei vergleicht, wenn ein Objekt in einen String umgewandelt wird:
Dim theTime As New Stoppuhr () Dim theString As String. Dim theObject As Object = "Ein Objekt" Dim theIterations As Integer = CInt (Iterationen. Text) * 1000000. ' 'DirectCast-Test. die Zeit. Start() Für i = 0 To theIterations. theString = DirectCast (theObject, String) Nächster. die Zeit. Halt() DirectCastTime. Text = die Zeit. Verstrichene Millisekunden. ToString. ' CType-Test. die Zeit. Neustart() Für i As Integer = 0 To theIterations. theString = CType (theObject, String) Nächster. die Zeit. Halt() CTypeTime. Text = die Zeit. Verstrichene Millisekunden. ToString. ' TryCast-Test. die Zeit. Neustart() Für i As Integer = 0 To theIterations. theString = TryCast (theObject, String) Wenn der String nichts ist, dann. MsgBox ("Dies sollte niemals angezeigt werden") End If. Nächster. die Zeit. Halt() TryCastTime. Text = die Zeit. Verstrichene Millisekunden. ToString.
Dieser erste Test scheint zu zeigen, dass Microsoft genau richtig ist. Hier ist das Ergebnis. (Experimente mit einer größeren und kleineren Anzahl von Iterationen sowie wiederholte Tests unter verschiedenen Bedingungen zeigten keine signifikanten Unterschiede zu diesem Ergebnis.)
Klicken Sie hier, um die Abbildung anzuzeigen
DirectCast und TryCast waren bei 323 und 356 Millisekunden ähnlich, aber CType nahm bei 1018 Millisekunden dreimal so viel Zeit in Anspruch. Wenn Sie Referenztypen wie diesen umwandeln, zahlen Sie für die Flexibilität von CType in Bezug auf die Leistung.
Aber funktioniert es immer so? Das Microsoft-Beispiel auf der Seite für DirectCast ist hauptsächlich hilfreich, um Ihnen zu sagen, was Gewohnheit arbeiten mit DirectCast, nicht was wird. Hier ist das Microsoft-Beispiel:
Dim q As Object = 2.37. Dim i As Integer = CType (q, Integer) 'Die folgende Konvertierung schlägt zur Laufzeit fehl. Dim j As Integer = DirectCast (q, Integer) Dim f As New System. Windows. Formen. Bilden. Dim c As System. Windows. Formen. Steuerung. 'Die folgende Konvertierung ist erfolgreich. c = DirectCast (f, System. Windows. Formen. Steuerung)
Mit anderen Worten, Sie kippen Verwenden Sie DirectCast (oder TryCast, obwohl sie hier nicht erwähnt werden), um einen Objekttyp in einen Integer-Typ umzuwandeln, aber Sie können Verwenden Sie DirectCast, um einen Formulartyp in einen Steuerelementtyp umzuwandeln.
Lassen Sie uns die Leistung von Microsofts Beispiel für was überprüfen werden arbeite mit DirectCast. Ersetzen Sie unter Verwendung der oben gezeigten Codevorlage ...
c = DirectCast (f, System. Windows. Formen. Steuerung)
... in den Code zusammen mit ähnlichen Ersetzungen für CType und TryCast. Die Ergebnisse sind etwas überraschend.
Klicken Sie hier, um die Abbildung anzuzeigen
DirectCast war mit 145 Millisekunden die langsamste der drei Optionen. CType ist mit 127 Millisekunden nur ein wenig schneller, aber TryCast, einschließlich eines If-Blocks, ist mit 77 Millisekunden am schnellsten. Ich habe auch versucht, meine eigenen Objekte zu schreiben:
Klasse ParentClass... Klasse beenden. Klasse ChildClass. Erbt ParentClass... Klasse beenden.
Ich habe ähnliche Ergebnisse erzielt. Es scheint, wenn Sie sind nicht Wenn Sie einen Objekttyp wirken, sind Sie besser dran nicht mit DirectCast.