Gjutning och datatypkonverteringar i VB.NET

Gjutning är bearbeta att konvertera en datatyp till en annan, till exempel från en heltalstyp till en strängtyp. Vissa operationer i VB.NET kräver specifika datatyper för att fungera. Gjutning skapar den typ du behöver. Den första artikeln i denna tvådelade serie, Casting and Data Type Conversions in VB.NET, introducerar casting. Den här artikeln beskriver de tre operatörerna du kan använda för att kasta in VB.NET - DirectCast, CType och TryCast - och jämför deras prestanda.

Prestanda är en av de stora skillnaderna mellan de tre gjutoperatörerna enligt Microsoft och andra artiklar. Till exempel är Microsoft vanligtvis noga med att varna för att "DirectCast... kan ge något bättre prestanda än CType vid konvertering till och från datatyp Objekt. "(Betoning tillagd.)

Jag bestämde mig för att skriva en kod för att kontrollera.

Men först ett försiktighetsord. Dan Appleman, en av grundarna av det tekniska bokförlaget Apress och en pålitlig teknisk guru, sa en gång till mig att benchmarkingprestanda är mycket svårare att göra korrekt än de flesta inse. Det finns faktorer som maskinprestanda, andra processer som kan köras parallellt, optimering som minnescachen eller kompilering optimering och fel i dina antaganden om vad koden faktiskt är håller på med. I dessa riktmärken har jag försökt eliminera jämförelsefel för "äpplen och apelsiner" och alla tester har genomförts med utgivningsbyggnaden. Men det kan fortfarande finnas fel i dessa resultat. Om du märker något, vänligen meddela mig.

instagram viewer

De tre gjutningsoperatörerna är:

  • DirectCast
  • ctyp
  • TryCast

I praktiken kommer du vanligtvis att upptäcka att kraven i din ansökan avgör vilken operatör du använder. DirectCast och TryCast har mycket smala krav. När du använder DirectCast måste typen redan vara känd. Även om koden ...

theString = DirectCast (theObject, String)

... kommer att kompilera framgångsrikt om theObject inte redan är en sträng, kommer koden att kasta ett runtime-undantag.

TryCast är ännu mer begränsande eftersom det inte alls fungerar på "värdetyper" som t.ex. heltal. (Sträng är en referenstyp. Mer information om värdetyper och referenstyper finns i den första artikeln i denna serie.) Den här koden ...

theInteger = TryCast (theobjektet, heltal)

... kommer inte ens att sammanställa.

TryCast är användbart när du inte är säker på vilken typ av objekt du arbetar med. I stället för att kasta ett fel som DirectCast returnerar TryCast bara ingenting. Den normala praxis är att testa för ingenting efter att ha genomfört TryCast.

Endast CType (och de andra "Convert" -operatörerna som CInt och CBool) konverterar typer som inte har ett arvsförhållande som ett heltal till en sträng:

Dim theString As String = "1" Dim theInteger som heltal. theInteger = CType (theString, Integer)

Detta fungerar eftersom CType använder "hjälpfunktioner" som inte ingår i .NET CLR (Common Language Runtime) för att utföra dessa omvandlingar.

Men kom ihåg att CType också kommer att kasta ett undantag om Strängen inte innehåller något som kan konverteras till ett heltal. Om det finns en möjlighet att strängen inte är ett heltal som det här ...


Dim theString As String = "George"

... då kommer ingen gjutningsoperatör att fungera. Till och med TryCast fungerar inte med heltal eftersom det är en värdetyp. I ett sådant fall måste du använda giltighetskontroll, till exempel Operatören TypeOf, för att kontrollera dina uppgifter innan du försöker kasta dem.

Microsofts dokumentation för DirectCast nämner specifikt gjutning med en objekttyp så det är vad jag använde i mitt första prestandatest. Testning börjar på nästa sida!

DirectCast kommer vanligtvis att använda en Objekttyp, så det är vad jag använde i mitt första prestandatest. För att inkludera TryCast i testet inkluderade jag också ett If-block eftersom nästan alla program som använder TryCast kommer att ha ett. I det här fallet kommer det emellertid aldrig att köras.

Här är koden som jämför alla tre när du kastar ett objekt till en sträng:

Dim theTime som ny stoppur () Dim theString som sträng. Dämpa theObject As Object = "Ett objekt" Dim theIterations Som heltal = CInt (Iterationer. Text) * 1000000. ' "DirectCast-test. tiden. Start() För i = 0 Till theIterations. theString = DirectCast (theObject, String) Nästa. tiden. Sluta() DirectCastTime. Text = tiden. ElapsedMilliseconds. Att stränga. ' 'CType-test. tiden. Omstart() För i som heltal = 0 till theIterations. theString = CType (theObject, String) Nästa. tiden. Sluta() CTypeTime. Text = tiden. ElapsedMilliseconds. Att stränga. ' "TryCast Test. tiden. Omstart() För i som heltal = 0 till theIterations. theString = TryCast (theObject, String) Om strängen är inget då. MsgBox ("Detta ska aldrig visas") Sluta om. Nästa. tiden. Sluta() TryCastTime. Text = tiden. ElapsedMilliseconds. Att stränga.

Det första testet verkar visa att Microsoft har rätt mål. Här är resultatet. (Experiment med större och mindre antal iterationer såväl som upprepade tester under olika förhållanden visade inga signifikanta skillnader från detta resultat.)


Klicka här för att visa bilden

DirectCast och TryCast var liknande vid 323 och 356 millisekunder, men CType tog över tre gånger så mycket tid på 1018 millisekunder. När du gjuter referenstyper som denna betalar du för flexibiliteten i CType i prestanda.

Men fungerar det alltid så här? Microsoft-exemplet på deras sida för DirectCast är främst användbart för att berätta vad vana arbeta med DirectCast, inte vad som kommer. Här är Microsoft-exemplet:

Dim q som objekt = 2,37. Dim i som heltal = CT-typ (q, heltal) Följande konvertering misslyckas vid körning. Dim j som heltal = DirectCast (q, heltal) Dim f Som nytt system. Windows. Former. Form. Dim c som system. Windows. Former. Kontrollera. Följande konvertering lyckas. c = DirectCast (f, System. Windows. Former. Kontrollera)

Med andra ord, du kan inte använd DirectCast (eller TryCast, även om de inte nämner det här) för att kasta en objekttyp till en heltalstyp, men du kan använd DirectCast för att kasta en formtyp till en kontrolltyp.

Låt oss kontrollera prestandan i Microsofts exempel på vad kommer arbeta med DirectCast. Använd samma kodmall som visas ovan, ersätt ...


c = DirectCast (f, System. Windows. Former. Kontrollera)

... i koden tillsammans med liknande substitutioner för CType och TryCast. Resultaten är lite förvånande.


Klicka här för att visa bilden

DirectCast var faktiskt det långsammaste av de tre valen på 145 millisekunder. CType är bara lite snabbare vid 127 millisekunder men TryCast, inklusive ett If-block, är det snabbaste på 77 millisekunder. Jag försökte också skriva mina egna objekt:


Klass ParentClass... Slutklass. Klass ChildClass. Inherits ParentClass... Slutklass. 

Jag fick liknande resultat. Det verkar som om du är inte gjutning av en objekttyp är du bättre inte med DirectCast.

instagram story viewer