Computerwissenschaften

Casting- und Datentypkonvertierungen in VB.NET

Gießen ist der Prozess einen Datentyp in einer anderen umzuwandeln, beispielsweise aus einem Integer – Typ auf einen String – Typen. Für einige Vorgänge in VB.NET sind bestimmte Datentypen erforderlich. 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. In diesem Artikel werden die drei Operatoren beschrieben, mit denen Sie VB.NET umwandeln können – DirectCast, CType und TryCast – und deren Leistung verglichen.

Die Leistung ist laut Microsoft und anderen Artikeln einer der großen Unterschiede zwischen den drei Casting-Betreibern. Beispielsweise warnt Microsoft normalerweise sorgfältig davor, dass „DirectCast … beim Konvertieren zum und vom Datentyp Object eine etwas bessere Leistung als CType bieten kann .“ (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 technischen Buchverlags Apress und ein zuverlässiger technischer Guru, sagte mir einmal, dass es viel schwieriger ist, Benchmarking-Leistungen korrekt durchzuführen, als die meisten Menschen glauben. Es gibt Faktoren wie die Maschinenleistung, andere Prozesse, die möglicherweise parallel ausgeführt werden, Optimierungen wie Speicher-Caching oder Compiler-Optimierung sowie Fehler in Ihren Annahmen darüber, was der Code tatsächlich tut. 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, dann 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 Stopwatch()
Dim theString As String
Dim theObject As Object="An Object"
Dim theIterations As Integer =
CInt(Iterations.Text) * 1000000
'
' DirectCast Test
theTime.Start()
For i=0 To theIterations
theString=DirectCast(theObject, String)
Next
theTime.Stop()
DirectCastTime.Text =
theTime.ElapsedMilliseconds.ToString
'
' CType Test
theTime.Restart()
For i As Integer=0 To theIterations
theString=CType(theObject, String)
Next
theTime.Stop()
CTypeTime.Text =
theTime.ElapsedMilliseconds.ToString
'
' TryCast Test
theTime.Restart()
For i As Integer=0 To theIterations
theString=TryCast(theObject, String)
If theString Is Nothing Then
MsgBox("This should never display")
End If
Next
theTime.Stop()
TryCastTime.Text =
theTime.ElapsedMilliseconds.ToString

Dieser erste Test scheint zu zeigen, dass Microsoft genau am Ziel 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 das immer so? Das Microsoft Beispiel in ihrer Seite für Direct ist vor allem nützlich für Sie zu sagen , was nicht wird mit arbeiten Direct, nicht , was wird. Hier ist das Microsoft-Beispiel:


Dim q As Object=2.37
Dim i As Integer=CType(q, Integer)
' The following conversion fails at run time
Dim j As Integer=DirectCast(q, Integer)
Dim f As New System.Windows.Forms.Form
Dim c As System.Windows.Forms.Control
' The following conversion succeeds.
c=DirectCast(f, System.Windows.Forms.Control)

Mit anderen Worten, Sie können DirectCast (oder TryCast, obwohl sie hier nicht erwähnt werden) nicht verwenden, um einen Objekttyp in einen Integer-Typ umzuwandeln , aber Sie können DirectCast verwenden, um einen Formulartyp in einen Control-Typ umzuwandeln.

Lassen Sie sich die Leistung von Microsofts Beispiel überprüfen , was wird mit Direct arbeiten. Ersetzen Sie unter Verwendung der oben gezeigten Codevorlage …


c=DirectCast(f, System.Windows.Forms.Control)

… 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:


Class ParentClass
...
End Class
Class ChildClass
Inherits ParentClass
...
End Class

Ich habe ähnliche Ergebnisse erzielt. Es scheint , dass , wenn Sie nicht ein Objekt ist Gießen, sind Sie besser dran nicht Direct verwenden.

Similar Posts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.