Turnarea este proces de conversie a unui tip de date la altul, de exemplu, de la un tip Integer la un tip String. Unele operații în VB.NET necesită tipuri de date specifice pentru a funcționa. Turnarea creează tipul de care aveți nevoie. Primul articol din această serie în două părți, Turnare și Tipuri de date Conversii în VB.NET, introduce castingul. Acest articol descrie cei trei operatori pe care îi puteți utiliza pentru a vă juca VB.NET - DirectCast, CType și TryCast - și compară performanța acestora.
Performanța este una dintre marile diferențe dintre cei trei operatori de casting conform Microsoft și alte articole. De exemplu, Microsoft este de obicei atentă să avertizeze că, "DirectCast... poate oferi performanțe ceva mai bune decât CType la conversia la și de la tipul de obiect Object"(A adăugat accentul.)
Am decis să scriu ceva cod pentru a verifica.
Dar mai întâi un cuvânt de prudență. Dan Appleman, unul dintre fondatorii editorului de carte tehnică Apress și un tehnic de încredere guru, mi-a spus odată că performanța de evaluare comparativă este mult mai greu de făcut corect decât majoritatea oamenilor dau seama. Există factori precum performanța mașinii, alte procese care ar putea fi executate în paralel, optimizarea cum ar fi memoria de memorie cache sau optimizarea compilatorului și erori în ipotezele dvs. despre ce este de fapt codul face. În aceste criterii, am încercat să elimin erorile de comparare „mere și portocale” și toate testele au fost efectuate odată cu lansarea versiunii. Dar ar putea exista încă erori în aceste rezultate. Dacă observați ceva, vă rugăm să mă anunțați.
Cei trei operatori de casting sunt:
- DirectCast
- cTYPE
- TryCast
În realitate, de obicei, veți constata că cerințele aplicației dvs. vor determina ce operator utilizați. DirectCast și TryCast au cerințe foarte restrânse. Când utilizați DirectCast, tipul trebuie deja cunoscut. Deși codul ...
theString = DirectCast (theObject, String)
... va compila cu succes dacă theObject nu este deja un șir, atunci codul va arunca o excepție de rulare.
TryCast este și mai restrictiv, deoarece nu va funcționa deloc la tipuri de „valoare”, cum ar fi Integer. (Șirul este un tip de referință. Pentru mai multe tipuri de valori și tipuri de referință, consultați primul articol din această serie.) Acest cod ...
theInteger = TryCast (theObject, Integer)
... nici măcar nu va compila.
TryCast este util atunci când nu sunteți sigur cu ce tip de obiect lucrați. În loc să arunce o eroare ca DirectCast, TryCast doar returnează Nimic. Practica obișnuită este de a testa Nimic după executarea TryCast.
Doar CType (și ceilalți operatori „Convertiți”, cum ar fi CInt și CBool) vor converti tipurile care nu au o relație de moștenire, cum ar fi un număr întreg la o șir:
Dim the String As String = "1" Dim theInteger ca întreg. theInteger = CType (theString, Integer)
Acest lucru funcționează deoarece CType utilizează „funcții helper” care nu fac parte din .NET CLR (Common Language Runtime) pentru a efectua aceste conversii.
Amintiți-vă însă că CType va arunca și o excepție dacă Stringul nu conține ceva care poate fi convertit într-un număr întreg. Dacă există posibilitatea ca șirul să nu fie un număr întreg ca acesta ...
Dim the String As String = "George"
... atunci niciun operator de turnare nu va funcționa. Chiar și TryCast nu va funcționa cu Integer, deoarece este un tip valoric. În acest caz, ar trebui să utilizați verificarea validității, cum ar fi operatorul TypeOf, pentru a verifica datele dvs. înainte de a încerca să le aruncați.
Documentația Microsoft pentru DirectCast menționează în mod specific distribuirea cu un tip de obiect, așa că am folosit-o în primul meu test de performanță. Testarea începe pe pagina următoare!
DirectCast va folosi de obicei un tip Obiect, așa că am folosit în primul meu test de performanță. Pentru a include TryCast în test, am inclus și un bloc If, deoarece aproape toate programele care folosesc TryCast vor avea unul. În acest caz, însă, nu va fi niciodată executat.
Iată codul care le compară pe toate cele trei când aruncați un obiect la o șir:
Dimensionează timp ca nou cronometru () Dim the String As String. Dim theObject As Object = "Un Obiect" Dimerați informațiile ca număr întreg = CInt (Ierații. Text) * 1000000. ' 'Test DirectCast. timpul. Start() Pentru i = 0 La iterații. theString = DirectCast (theObject, String) Următor →. timpul. Stop() DirectCastTime. Text = timpul. ElapsedMilliseconds. ToString. ' Testul tip CT. timpul. Repornire() For i As Integer = 0 To the Iterations. theString = CType (theObject, String) Următor →. timpul. Stop() CTypeTime. Text = timpul. ElapsedMilliseconds. ToString. ' 'Testul de încercare. timpul. Repornire() For i As Integer = 0 To the Iterations. theString = TryCast (theObject, String) Dacă Stringul nu este Nimic Atunci. MsgBox ("Acest lucru nu ar trebui să se afișeze niciodată") End If. Următor →. timpul. Stop() TryCastTime. Text = timpul. ElapsedMilliseconds. ToString.
Acest test inițial pare să arate că Microsoft are dreptate pe țintă. Iată rezultatul. (Experimentele cu un număr mai mare și mai mic de iterații, precum și teste repetate în diferite condiții nu au arătat diferențe semnificative față de acest rezultat.)
Faceți clic aici pentru a afișa ilustrația
DirectCast și TryCast au fost similare la 323 și 356 milisecunde, dar CType a preluat de trei ori mai mult timp la 1018 milisecunde. La distribuirea tipurilor de referință de acest fel, plătiți pentru flexibilitatea CType în performanță.
Dar funcționează întotdeauna așa? Exemplul Microsoft din pagina lor pentru DirectCast este util în principal pentru a vă spune ce nu va funcționează folosind DirectCast, nu ce va. Iată exemplul Microsoft:
Dim q Ca obiect = 2,37. Dim i As Integer = CType (q, Integer) 'Următoarea conversie nu reușește la timpul de rulare. Dim j As Integer = DirectCast (q, Integer) Dim f Ca sistem nou. Windows. Formulare. Formă. Sistemul Dim c As. Windows. Formulare. Control. „Următoarea conversie are succes. c = DirectCast (f, Sistem. Windows. Formulare. Control)
Cu alte cuvinte, tu nu se poate utilizați DirectCast (sau TryCast, deși nu îl menționează aici) pentru a arunca un tip de obiect la un tip întreg, dar tu poate sa utilizați DirectCast pentru a trimite un tip de formular la un tip de control.
Să verificăm performanța exemplului Microsoft despre ce voi lucrați cu DirectCast. Folosind același șablon de cod prezentat mai sus, înlocuiți ...
c = DirectCast (f, Sistem. Windows. Formulare. Control)
... în cod împreună cu substituții similare pentru CType și TryCast. Rezultatele sunt puțin surprinzătoare.
Faceți clic aici pentru a afișa ilustrația
DirectCast a fost de fapt cea mai lentă dintre cele trei opțiuni la 145 de milisecunde. CType este doar puțin mai rapid la 127 de milisecunde, dar TryCast, inclusiv un bloc If, este cel mai rapid la 77 de milisecunde. De asemenea, am încercat să scriu propriile mele obiecte:
Clasa ParentClass... Clasa finală. Clasa Clasa pentru copii. Moștenește ParentClass... Clasa finală.
Am obținut rezultate similare. Se pare că dacă ești nu aruncând un tip de obiect, te descurci mai bine nu folosind DirectCast.