Diferencia entre DirectCast () y CType () en VB.NET

99

Soy un programador experimentado en C / C ++ / C # que acaba de ingresar a VB.NET. Por lo general, uso CType (y CInt, CBool, CStr) para las emisiones porque tiene menos caracteres y fue la primera forma de transmisión a la que estuve expuesto, pero también conozco DirectCast y TryCast.

Simplemente, ¿hay alguna diferencia (efecto del reparto, rendimiento, etc.) entre DirectCast y CType? Entiendo la idea de TryCast.

Caleb Hearth
fuente
6
Duplicado exacto de este Casting DataTypes con DirectCast, CType, TryCast stackoverflow.com/questions/2703585/…
MarkJ

Respuestas:

182

Lo primero que hay que tener en cuenta es que VB.NET no tiene un análogo directo al (type)instancemecanismo de conversión de C # . Menciono esto porque es útil como punto de partida para comparar los dos operadores VB.NET (y son operadores, no funciones, aunque tienen semántica de función).

DirectCast()es más estricto que el operador de conversión de C #. Solo te permite lanzar cuando el elemento que se está lanzando ya es del tipo al que estás lanzando. Creo que aún desempacará los tipos de valor, pero de lo contrario no realizará ninguna conversión. Entonces, por ejemplo, no puede transmitir de shorta int, como podría hacerlo con un (int)lanzamiento de C # . Pero puede convertir de una IEnumerablea una matriz, si su IEnumerablevariable de objeto subyacente realmente es una Array. Y, por supuesto, puede convertir desde Objecta cualquier cosa, asumiendo que el tipo de su instancia de objeto realmente está en algún lugar por debajo de su tipo de conversión en el árbol de herencia.

Esto es deseable porque es mucho más rápido . Hay menos conversión y verificación de tipos que se deben realizar.

CType()es menos estricto que el operador de conversión de C #. Hará cosas que no puedes hacer con un (int)elenco de estilo simple , como convertir una cadena en un número entero. Tiene tanto poder como llamar Convert.To___()en C #, donde ___es el tipo de destino de su elenco.

Esto es deseable porque es muy poderoso. Sin embargo, este poder tiene un costo de desempeño; no es tan rápido como el DirectCast()operador de conversión de C # porque podría necesitar hacer bastante trabajo para terminar la conversión. Por lo general, debería preferir DirectCast()cuando pueda.

Finalmente, te perdiste un operador de conversión:, TryCast()que es un análogo directo al asoperador de C # .

Joel Coehoorn
fuente
23
+1 Yo diría que el rigor de DirectCastes otra ventaja. Si comete un error, el compilador se lo informa de inmediato, pero con CTypeun error podría causar un comportamiento incorrecto ocasional en tiempo de ejecución, tal vez en alguna máquina de usuario con diferentes configuraciones regionales.
MarkJ
1
Gran respuesta. Así, en orden de complejidad (pequeño a grande): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()sería correcto?
lema
3
@motto - cerrar. Las "funciones" de C <xyz> () deberían moverse más arriba en la lista, ya que en realidad son operadores en lugar de funciones, aunque tienen semántica de funciones. Para aquellos tipos que los tienen, están muy cerca de la conversión (tipo) de C #, pero harán un poco más de trabajo.
Joel Coehoorn
3
@MarkJ +1 para su comentario, pero la nota DirectCastsolo es estricta con las clases, no con las interfaces (porque puede tener tipos COM, y quizás otros, que realmente implementen interfaces no definidas por la .GetInterfaceslista de tipos .NET ).
Mark Hurd
2
@JoelCoehoorn +1, Pero en realidad, TryCast()ya asno son exactamente iguales. TryCast()solo funciona con tipos de referencia, mientras que asfunciona con cualquier cosa que pueda ser nula. Entonces int? icast = myNum as int?;funcionará bien, pero Dim icast as Integer? = TryCast(myNum, Integer?)dará un error de compilación. Solo una diferencia peculiar más entre los dos idiomas. lol
CptRobby
12

Con CTypepuedes escribir algo como esto Ctype("string",Integer). Pero con DirectCastla declaración anterior daría un error de tiempo de compilación.

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

DirectCastes más restrictivo que CType.

Por ejemplo, esto arrojará un error:

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

También se mostrará en el IDE de Visual Studio.

Sin embargo, esto no arroja un error:

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