Casting is het werkwijze van het omzetten van het ene gegevenstype naar het andere, bijvoorbeeld van een geheel getaltype naar een tekenreekstype. Enkele operaties in VB.NET vereisen specifieke gegevenstypen om te werken. Casting maakt het type dat u nodig hebt. Het eerste artikel in deze tweedelige serie, Casting en Data Type Conversions in VB.NET, introduceert casting. Dit artikel beschrijft de drie operators die u kunt gebruiken om in te casten VB.NET - DirectCast, CType en TryCast - en vergelijken hun prestaties.
Prestaties is een van de grote verschillen tussen de drie castingoperatoren volgens Microsoft en andere artikelen. Microsoft let er bijvoorbeeld meestal op dat "DirectCast... kan iets betere prestaties leveren dan CType bij het converteren naar en van het gegevenstype Object. "(Nadruk toegevoegd.)
Ik besloot om wat code te schrijven om te controleren.
Maar eerst een woord van waarschuwing. Dan Appleman, een van de oprichters van de technische boekenuitgever Apress en een betrouwbare technische goeroe, vertelde me ooit dat benchmarkingprestaties veel moeilijker zijn om correct te doen dan de meeste mensen realiseren. Er zijn factoren zoals machineprestaties, andere processen die mogelijk parallel lopen, optimalisatie zoals geheugencaching of compileroptimalisatie en fouten in uw veronderstellingen over wat de code eigenlijk is aan het doen. In deze benchmarks heb ik geprobeerd vergelijkingsfouten tussen "appels en sinaasappels" te elimineren en alle tests zijn uitgevoerd met de release build. Maar er kunnen nog steeds fouten in deze resultaten voorkomen. Laat het me weten als je iets opmerkt.
De drie castingoperators zijn:
- DirectCast
- CType
- TryCast
In de praktijk zult u meestal merken dat de vereisten van uw toepassing bepalen welke operator u gebruikt. DirectCast en TryCast hebben zeer beperkte vereisten. Wanneer u DirectCast gebruikt, moet het type al bekend zijn. Hoewel de code ...
theString = DirectCast (theObject, String)
... zal succesvol compileren als theObject nog geen string is, dan zal de code een runtime-uitzondering genereren.
TryCast is nog beperkter omdat het helemaal niet werkt op "waarde" -typen zoals Integer. (String is een referentietype. Zie het eerste artikel in deze serie voor meer informatie over waardetypen en referentietypen.) Deze code ...
theInteger = TryCast (theObject, Integer)
... zal zelfs niet compileren.
TryCast is handig als u niet zeker weet met welk type object u werkt. In plaats van een fout als DirectCast te gooien, retourneert TryCast gewoon niets. De normale praktijk is om voor niets te testen na het uitvoeren van TryCast.
Alleen CType (en de andere "Convert" -operatoren zoals CInt en CBool) zullen types die geen overervingsrelatie hebben, zoals een geheel getal, converteren naar een string:
Dim theString As String = "1" Dim het gehele getal als geheel getal. theInteger = CType (theString, Integer)
Dit werkt omdat CType "helpfuncties" gebruikt die geen deel uitmaken van .NET CLR (Common Language Runtime) om deze conversies uit te voeren.
Maar onthoud dat CType ook een uitzondering genereert als theString niet iets bevat dat kan worden geconverteerd naar een geheel getal. Als er een mogelijkheid is dat de string geen geheel getal als dit is ...
Dim theString As String = "George"
... dan zal geen casting operator werken. Zelfs TryCast werkt niet met Integer omdat het een waardetype is. In een geval als dit zou u geldigheidscontrole moeten gebruiken, zoals de TypeOf-operator, om uw gegevens te controleren voordat u deze probeert te casten.
Microsoft's documentatie voor DirectCast vermeldt specifiek casten met een objecttype, dus dat heb ik in mijn eerste prestatietest gebruikt. Het testen begint op de volgende pagina!
DirectCast gebruikt meestal een objecttype, dus dat heb ik in mijn eerste prestatietest gebruikt. Om TryCast in de test op te nemen, heb ik ook een If-blok opgenomen, omdat bijna alle programma's die TryCast gebruiken er een hebben. In dit geval zal het echter nooit worden uitgevoerd.
Hier is de code die alle drie vergelijkt bij het casten van een object naar een string:
Dim theTime As New Stopwatch () Dim theString As String. Dim theObject As Object = "An Object" Dim theIterations As Integer = CInt (Iteraties. Tekst) * 1000000. ' 'DirectCast-test. de tijd. Begin() Voor i = 0 Naar theIterations. theString = DirectCast (theObject, String) De volgende. de tijd. Hou op() DirectCastTime. Tekst = de tijd. Verstreken Milliseconden. ToString. ' 'CType-test. de tijd. Herstarten() For i As Integer = 0 Naar theIterations. theString = CType (theObject, String) De volgende. de tijd. Hou op() CTypeTime. Tekst = de tijd. Verstreken Milliseconden. ToString. ' 'TryCast-test. de tijd. Herstarten() For i As Integer = 0 Naar theIterations. theString = TryCast (theObject, String) Als theString niets is dan. MsgBox ("Dit mag nooit worden weergegeven") Stop als. De volgende. de tijd. Hou op() TryCastTime. Tekst = de tijd. Verstreken Milliseconden. ToString.
Deze eerste test lijkt aan te tonen dat Microsoft gelijk heeft. Hier is het resultaat. (Experimenten met groter en kleiner aantal iteraties evenals herhaalde tests onder verschillende omstandigheden toonden geen significante verschillen met dit resultaat.)
Klik hier om de illustratie weer te geven
DirectCast en TryCast waren vergelijkbaar op 323 en 356 milliseconden, maar CType nam drie keer zoveel tijd in beslag op 1018 milliseconden. Wanneer u referentietypes zoals deze cast, betaalt u voor de flexibiliteit van CType in prestaties.
Maar werkt het altijd zo? Het Microsoft-voorbeeld op hun pagina voor DirectCast is vooral nuttig om u te vertellen wat zal niet werk met behulp van DirectCast, niet wat wil. Hier is het Microsoft-voorbeeld:
Dim q As Object = 2.37. Dim i als geheel getal = CType (q, geheel getal) 'De volgende conversie mislukt tijdens runtime. Dim j als geheel getal = DirectCast (q, geheel getal) Dim f Als nieuw systeem. Ramen. Vormen. Het formulier. Dim c als systeem. Ramen. Vormen. Controle. 'De volgende conversie slaagt. c = DirectCast (f, Systeem. Ramen. Vormen. Controle)
Met andere woorden, jij kan niet gebruik DirectCast (of TryCast, hoewel ze het hier niet vermelden) om een objecttype naar een geheel getal te casten, maar u kan gebruik DirectCast om een formuliertype naar een controletype te casten.
Laten we eens kijken naar de prestaties van het voorbeeld van Microsoft van wat zullen werken met DirectCast. Gebruik dezelfde codesjabloon als hierboven, vervang ...
c = DirectCast (f, Systeem. Ramen. Vormen. Controle)
... in de code, samen met vergelijkbare vervangingen voor CType en TryCast. De resultaten zijn een beetje verrassend.
Klik hier om de illustratie weer te geven
DirectCast was eigenlijk de langzaamste van de drie keuzes bij 145 milliseconden. CType is net iets sneller met 127 milliseconden, maar TryCast, inclusief een If-blok, is het snelst met 77 milliseconden. Ik heb ook geprobeerd mijn eigen objecten te schrijven:
Klasse Ouderklasse... Eindklasse. Klasse ChildClass. Overleeft ParentClass... Eindklasse.
Ik heb vergelijkbare resultaten. Het lijkt erop dat als jij dat bent niet een objecttype casten, bent u beter af niet met behulp van DirectCast.