Differenza tra DirectCast () e CType () in VB.NET


99

Sono un programmatore esperto di C / C ++ / C # che è appena entrato in VB.NET. In genere uso CType (e CInt, CBool, CStr) per i cast perché ci sono meno personaggi ed è stato il primo modo di casting a cui sono stato esposto, ma sono a conoscenza anche di DirectCast e TryCast.

Semplicemente, ci sono differenze (effetto del cast, prestazioni, ecc.) Tra DirectCast e CType? Capisco l'idea di TryCast.


6
Esatto duplicato di questo Casting DataTypes con DirectCast, CType, TryCast stackoverflow.com/questions/2703585/...
MarkJ

Risposte:


182

La prima cosa da notare è che VB.NET non ha un analogo diretto al (type)instancemeccanismo di casting di C # . Ne parlo perché è utile come punto di partenza per confrontare i due operatori VB.NET (e sono operatori, non funzioni, anche se hanno la semantica delle funzioni).

DirectCast()è più rigoroso dell'operatore di casting C #. Ti consente solo di lanciare quando l'oggetto che stai trasmettendo è già del tipo a cui stai trasmettendo. Credo che unbox ancora i tipi di valore, ma per il resto non eseguirà alcuna conversione. Quindi, ad esempio, non puoi trasmettere da shorta int, come potresti fare con un (int)cast C # . Ma puoi eseguire il cast da an IEnumerablea un array, se la tua IEnumerablevariabile oggetto sottostante è davvero un file Array. E ovviamente puoi eseguire il cast da Objecta qualsiasi cosa, supponendo che il tipo della tua istanza di oggetto sia davvero da qualche parte sotto il tuo tipo di cast nell'albero dell'ereditarietà.

Questo è desiderabile perché è molto più veloce . Ci sono meno conversioni e controlli del tipo che devono essere effettuati.

CType()è meno rigoroso dell'operatore di casting C #. Farà cose che non puoi fare con un (int)cast in stile semplice , come convertire una stringa in un numero intero. Ha la stessa potenza della chiamata Convert.To___()in C #, dove ___è il tipo di destinazione del cast.

Questo è desiderabile perché è molto potente. Tuttavia, questo potere va a scapito delle prestazioni; non è veloce come l' DirectCast()operatore cast di C # o di C # perché potrebbe essere necessario fare un bel po 'di lavoro per completare il cast. Generalmente dovresti preferire DirectCast()quando puoi.

Infine, ti sei perso un operatore di casting:, TryCast()che è un analogo diretto asdell'operatore di C # .


23
+1 Direi che il rigore di DirectCastè un altro vantaggio. Se commetti un errore, il compilatore te lo dice immediatamente, ma con CTypeun errore potrebbe causare un comportamento errato occasionale in fase di esecuzione, forse su qualche macchina utente con diverse impostazioni regionali.
MarkJ

1
Bella risposta. Quindi, al fine di complessità (piccole e grandi): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()sarebbe corretto?
motto

3
@motto - chiudi. Le "funzioni" C <xyz> () dovrebbero essere spostate più in alto nell'elenco, poiché in realtà sono operatori piuttosto che funzioni, anche se hanno la semantica delle funzioni. Per quei tipi che li hanno, sono molto vicini al casting (tipo) di C #, ma faranno solo un po 'più di lavoro.
Joel Coehoorn

3
@MarkJ +1 per il tuo commento, ma la nota DirectCastè rigorosa solo con le classi, non con le interfacce (perché puoi avere tipi COM - e forse altri - che implementano effettivamente interfacce non definite .GetInterfacesdall'elenco dei tipi .NET ).
Mark Hurd

2
@JoelCoehoorn +1, Ma in realtà, TryCast()e asnon sono esattamente la stessa cosa. TryCast()funziona solo con i tipi di riferimento, mentre asfunziona con tutto ciò che può essere nullo. Quindi int? icast = myNum as int?;funzionerà bene, ma Dim icast as Integer? = TryCast(myNum, Integer?)darà un errore del compilatore. Solo un'altra differenza peculiare tra le due lingue. lol
CptRobby

12

Con CTypepuoi scrivere qualcosa del genere Ctype("string",Integer). Ma con DirectCastla dichiarazione di cui sopra darebbe un errore di compilazione.

 Dim a As Integer = DirectCast("1", Integer) 'Gives compiler error
 Dim b As Integer = CType("1", Integer) 'Will compile

0

DirectCastè più restrittivo di CType.

Ad esempio, questo genererà un errore:

Sub Main()
    Dim newint As Integer = DirectCast(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub

Verrà mostrato anche nell'IDE di Visual Studio.

Questo tuttavia non genera un errore:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.