Info

Převod casting a datový typ ve VB.NET

Převod casting a datový typ ve VB.NET

Odlévání je proces převodu jednoho datového typu na jiný, například z typu Integer na typ String. Některé operace ve VB.NET vyžadují, aby fungovaly konkrétní datové typy. Odlévání vytvoří požadovaný typ. První článek této dvoudílné série Casting a Konverze datových typů ve VB.NET představuje casting. Tento článek popisuje tři operátory, které můžete použít pro obsazení ve VB.NET - DirectCast, CType a TryCast - a porovnává jejich výkon.

Výkon je jedním z velkých rozdílů mezi třemi operátory castingů podle společnosti Microsoft a dalších článků. Například Microsoft obvykle upozorňuje, že „DirectCast… může poskytnout o něco lepší výkon než CType při převodu do az datového typu Object. “(Důraz byl přidán.)

Rozhodl jsem se napsat nějaký kód ke kontrole.

Nejdříve ale opatrně. Dan Appleman, jeden ze zakladatelů vydavatele technické knihy Apress a spolehlivého technického guru, mi jednou řekl, že výkon srovnávání je mnohem těžší dělat správně, než si většina lidí uvědomuje. Existují faktory, jako je výkon stroje, další procesy, které mohou běžet paralelně, optimalizace, jako je ukládání do paměti cache nebo optimalizace kompilátoru, a chyby ve vašich předpokladech o tom, co kód ve skutečnosti dělá. V těchto benchmarkech jsem se pokusil eliminovat chyby porovnávání „jablek a pomerančů“ a všechny testy byly provedeny se sestavením vydání. V těchto výsledcích však stále mohou být chyby. Pokud si toho všimnete, dejte mi prosím vědět.

Tři operátoři castingu jsou:

  • DirectCast
  • CType
  • TryCast

V praxi obvykle zjistíte, že požadavky vaší aplikace určí, který operátor používáte. DirectCast a TryCast mají velmi úzké požadavky. Při použití DirectCast musí být typ již znám. Přestože kód ...

theString = DirectCast (theObject, String)

… Bude úspěšně zkompilován, pokud theObject již není řetězec, pak kód vyvolá runtime výjimku.

TryCast je ještě restriktivnější, protože nebude fungovat vůbec u „hodnotových“ typů, jako je Integer. (Řetězec je typ odkazu. Další informace o typech hodnot a typech odkazů najdete v prvním článku této řady.) Tento kód…

theInteger = TryCast (theObject, Integer)

… Nebude se kompilovat.

TryCast je užitečný, když si nejste jisti, s jakým typem objektu pracujete. Spíše než házení chyby jako DirectCast, TryCast prostě nevrací nic. Běžnou praxí je po provedení programu TryCast otestovat nic.

Pouze CType (a další operátoři „Převést“ jako CInt a CBool) převedou typy, které nemají dědičný vztah, jako je Integer, na String:

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

Funguje to proto, že CType používá „pomocné funkce“, které nejsou součástí .NET CLR (Common Language Runtime), k provedení těchto konverzí.

Pamatujte však, že CType také vyvolá výjimku, pokud TheString neobsahuje něco, co lze převést na celé číslo. Pokud existuje možnost, že řetězec není celé toto číslo ...

Dim theString As String = "George"

… Pak žádný operátor odlévání nebude fungovat. Ani TryCast nebude pracovat s Integerem, protože je to typ hodnoty. V takovém případě byste museli před pokusem o odevzdání dat zkontrolovat data, například operátor TypeOf.

Dokumentace společnosti Microsoft pro DirectCast konkrétně zmiňuje obsazení s typem objektu, takže jsem použila svůj první test výkonu. Testování začíná na další stránce!

DirectCast obvykle používá typ objektu, takže jsem použil svůj první test výkonu. Pro zahrnutí TryCastu do testu jsem také zahrnul blok If, protože téměř všechny programy, které používají TryCast, budou mít jeden. V tomto případě však nikdy nebude proveden.

Zde je kód, který porovnává všechny tři při přetypování objektu na řetězec:

Dim theTime jako nové stopky () Dim theString jako String Dim theObject as Object = "Object" Dim theIterations As Integer = CInt (Iterations.Text) * 1000000 "DirectCast Test theTime.Start () Pro i = 0 theIterations theString = DirectCast (theObject, String) Další theTime.Stop () DirectCastTime.Text = theTime.ElapsedMilliseconds.ToString "CType Test theTime.Restart () Pro i jako Integer = 0 Na theterations theString = CType (theObject, String) Next theTime.Stop () CTypeTime.Text = theTime.ElapsedMilliseconds.ToString "TryCast Test theTime.Restart () Pro i As Integer = 0 To theItrations theString = TryCast (theObject, String) Pokud theString není nic, pak MsgBox (" To by se nikdy nemělo zobrazit ") Konec Pokud Další theTime.Stop () TryCastTime.Text = theTime.ElapsedMilliseconds.ToString

Zdá se, že tento počáteční test ukazuje, že Microsoft má pravdu. Zde je výsledek. (Pokusy s větším a menším počtem iterací a opakované testy za různých podmínek neprokázaly žádné významné rozdíly od tohoto výsledku.)

--------
Klepnutím sem zobrazíte obrázek
--------

DirectCast a TryCast byly podobné ve 323 a 356 milisekundách, ale CType převzal třikrát tolik času v 1018 milisekundách. Při obsazení referenčních typů, jako je tento, platíte za flexibilitu výkonu CType.

Ale funguje to vždy takto? Příklad Microsoftu na jejich stránce pro DirectCast je užitečný zejména pro sdělení toho, co zvyklý pracovat pomocí DirectCast, ne co bude. Zde je příklad společnosti Microsoft:

Dim q As Object = 2.37 Dim i As Integer = CType (q, Integer) 'Následující konverze se nezdařila za běhu Dim j As Integer = DirectCast (q, Integer) Dim f As New System.Windows.Forms.Form Dim c As System.Windows.Forms.Control 'Následující převod proběhl úspěšně. c = DirectCast (f, System.Windows.Forms.Control)

Jinými slovy, vy nemůže použijte DirectCast (nebo TryCast, i když to zde nezmiňují) k přetypování typu objektu na celé číslo, ale vy umět použijte DirectCast k přetypování typu formuláře na typ kontroly.

Podívejme se na to, jak vypadá příklad Microsoftu vůle pracovat s DirectCast. Použijte stejnou šablonu kódu, jak je uvedeno výše, nahradit…

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

... do kódu spolu s podobnými substitucemi pro CType a TryCast. Výsledky jsou trochu překvapivé.

--------
Klepnutím sem zobrazíte obrázek
--------

DirectCast byl ve skutečnosti nejpomalejší ze tří voleb za 145 milisekund. CType je o něco rychlejší za 127 milisekund, ale TryCast, včetně bloku If, je nejrychlejší za 77 milisekund. Také jsem se pokusil napsat vlastní objekty:

Třída ParentClass… End Class Class ChildClass zdědí ParentClass… End Class

Mám podobné výsledky. Zdá se, že pokud jste ne odléváním typu objektu, jste lepší ne pomocí DirectCast.