Il casting è il processi di convertire un tipo di dati in un altro, ad esempio, da un tipo intero a un tipo stringa. Alcune operazioni in VB.NET richiedono tipi di dati specifici per funzionare. Il casting crea il tipo che ti serve. Il primo articolo di questa serie in due parti, Casting e Conversioni di tipi di dati in VB.NET, introduce il casting. Questo articolo descrive i tre operatori che è possibile utilizzare per il cast VB.NET - DirectCast, CType e TryCast - e confronta le loro prestazioni.
Le prestazioni sono una delle grandi differenze tra i tre operatori di casting secondo Microsoft e altri articoli. Ad esempio, Microsoft di solito è attenta ad avvertire che "DirectCast... può fornire prestazioni leggermente migliori rispetto a CType durante la conversione da e verso il tipo di dati Object." (Enfasi aggiunta.)
Ho deciso di scrivere un codice per verificare.
Ma prima una parola di cautela. Dan Appleman, uno dei fondatori della casa editrice di libri tecnici Apress e un tecnico affidabile guru, una volta mi ha detto che il benchmarking delle prestazioni è molto più difficile da eseguire correttamente rispetto alla maggior parte delle persone rendersi conto. Ci sono fattori come le prestazioni della macchina, altri processi che potrebbero essere eseguiti in parallelo, l'ottimizzazione come la memorizzazione nella cache della memoria o l'ottimizzazione del compilatore e gli errori nei tuoi presupposti su cosa sia effettivamente il codice facendo. In questi benchmark, ho cercato di eliminare gli errori di confronto "mele e arance" e tutti i test sono stati eseguiti con la build di rilascio. Ma potrebbero esserci ancora errori in questi risultati. Se noti qualcosa, fammi sapere.
I tre operatori di casting sono:
- DirectCast
- CType
- TryCast
In pratica, di solito troverete che i requisiti della vostra applicazione determineranno quale operatore utilizzate. DirectCast e TryCast hanno requisiti molto ristretti. Quando si utilizza DirectCast, il tipo deve essere già noto. Anche se il codice ...
theString = DirectCast (theObject, String)
... verrà compilato correttamente se l'Object non è già una stringa, quindi il codice genererà un'eccezione di runtime.
TryCast è ancora più restrittivo perché non funzionerà affatto su tipi di "valore" come Integer. (String è un tipo di riferimento. Per ulteriori informazioni sui tipi di valore e sui tipi di riferimento, vedere il primo articolo di questa serie.) Questo codice ...
theInteger = TryCast (theObject, Integer)
... non verrà nemmeno compilato.
TryCast è utile quando non sei sicuro del tipo di oggetto con cui stai lavorando. Invece di generare un errore come DirectCast, TryCast non restituisce nulla. La pratica normale è testare Nothing dopo aver eseguito TryCast.
Solo CType (e gli altri operatori "Converti" come CInt e CBool) convertiranno i tipi che non hanno una relazione di ereditarietà come un intero in una stringa:
Dim theString As String = "1" Dim theInteger As Integer. theInteger = CType (theString, Integer)
Ciò funziona perché CType utilizza "funzioni di supporto" che non fanno parte di .NET CLR (Common Language Runtime) per eseguire queste conversioni.
Ma ricorda che CType genererà anche un'eccezione se theString non contiene qualcosa che può essere convertito in un intero. Se esiste la possibilità che la stringa non sia un numero intero come questo ...
Dim theString As String = "George"
... quindi nessun operatore di casting funzionerà. Anche TryCast non funzionerà con Integer perché è un tipo di valore. In un caso come questo, dovresti utilizzare il controllo di validità, come l'operatore TypeOf, per controllare i tuoi dati prima di provare a trasmetterli.
La documentazione di Microsoft per DirectCast menziona specificamente il casting con un tipo di oggetto, quindi è quello che ho usato nel mio primo test delle prestazioni. I test iniziano nella pagina successiva!
DirectCast di solito utilizza un tipo di oggetto, quindi è quello che ho usato nel mio primo test delle prestazioni. Per includere TryCast nel test, ho incluso anche un blocco If poiché quasi tutti i programmi che utilizzano TryCast ne avranno uno. In questo caso, tuttavia, non verrà mai eseguito.
Ecco il codice che confronta tutti e tre quando si fonde un oggetto in una stringa:
Dim theTime As New Cronometro () Dim theString As String. Dim theObject As Object = "Un oggetto" Dim theIterations As Intero = CInt (Iterazioni. Testo) * 1000000. ' "Test DirectCast. il tempo. Inizio() Per i = 0 Alle istruzioni. theString = DirectCast (theObject, String) Il prossimo. il tempo. Fermare() DirectCastTime. Testo = il tempo. ElapsedMilliseconds. Accordare. ' "Test CType. il tempo. Ricomincia() Per i As Integer = 0 To theIterations. theString = CType (theObject, String) Il prossimo. il tempo. Fermare() CTypeTime. Testo = il tempo. ElapsedMilliseconds. Accordare. ' 'Prova TryCast. il tempo. Ricomincia() Per i As Integer = 0 To theIterations. theString = TryCast (theObject, String) Se la stringa non è niente allora. MsgBox ("Questo non dovrebbe mai essere visualizzato") Finisci se. Il prossimo. il tempo. Fermare() TryCastTime. Testo = il tempo. ElapsedMilliseconds. Accordare.
Questo test iniziale sembra dimostrare che Microsoft ha ragione. Ecco il risultato. (Esperimenti con un numero sempre maggiore di iterazioni e test ripetuti in condizioni diverse non hanno mostrato differenze significative da questo risultato.)
Fare clic qui per visualizzare l'illustrazione
DirectCast e TryCast erano simili a 323 e 356 millisecondi, ma CType ha impiegato tre volte più tempo a 1018 millisecondi. Quando si lanciano tipi di riferimento come questo, si paga per la flessibilità di CType nelle prestazioni.
Ma funziona sempre così? L'esempio di Microsoft nella loro pagina per DirectCast è utile soprattutto per dirti cosa non lo farà funziona usando DirectCast, non quello che farà. Ecco l'esempio di Microsoft:
Dim q As Object = 2.37. Dim i come intero = CType (q, intero) 'La seguente conversione non riesce in fase di esecuzione. Dim j As Intero = DirectCast (q, intero) Dim f come nuovo sistema. Finestre. Le forme. Modulo. Dim c come sistema. Finestre. Le forme. Controllo. 'La seguente conversione ha esito positivo. c = DirectCast (f, Sistema. Finestre. Le forme. Controllo)
In altre parole, tu non si può usa DirectCast (o TryCast, anche se qui non lo menzionano) per trasmettere un tipo di oggetto a un tipo intero, ma tu può utilizzare DirectCast per trasmettere un tipo di modulo a un tipo di controllo.
Controlliamo le prestazioni dell'esempio di Microsoft di cosa volontà lavorare con DirectCast. Utilizzando lo stesso modello di codice mostrato sopra, sostituire ...
c = DirectCast (f, Sistema. Finestre. Le forme. Controllo)
... nel codice insieme a sostituzioni simili per CType e TryCast. I risultati sono un po 'sorprendenti.
Fare clic qui per visualizzare l'illustrazione
DirectCast era in realtà la più lenta delle tre scelte a 145 millisecondi. CType è solo un po 'più veloce a 127 millisecondi, ma TryCast, incluso un blocco If, è il più veloce a 77 millisecondi. Ho anche provato a scrivere i miei oggetti:
Classe ParentClass... End Class. Classe ChildClass. Eredita ParentClass... End Class.
Ho ottenuto risultati simili. Sembra che se lo sei non lanciando un tipo di oggetto, stai meglio non utilizzando DirectCast.