Diferença entre DirectCast () e CType () em VB.NET


99

Sou um programador C / C ++ / C # experiente que acabou de entrar no VB.NET. Eu geralmente uso CType (e CInt, CBool, CStr) para casts porque tem menos caracteres e foi a primeira forma de casting a que fui exposto, mas também conheço DirectCast e TryCast.

Simplesmente, existem diferenças (efeito de elenco, desempenho, etc.) entre DirectCast e CType? Eu entendo a ideia do TryCast.


6
Duplicata exata deste Casting DataTypes com DirectCast, CType, TryCast stackoverflow.com/questions/2703585/…
MarkJ

Respostas:


182

A primeira coisa a observar é que o VB.NET não tem um análogo direto ao (type)instancemecanismo de conversão do C # . Eu trago isso porque é útil como um ponto de partida na comparação dos dois operadores VB.NET (e eles são operadores, não funções, embora tenham semântica de função).

DirectCast()é mais estrito do que o operador de conversão C #. Ele só permite que você lance quando o item que está sendo lançado já é do tipo para o qual você está lançando. Eu acredito que ainda irá desempacotar os tipos de valor, mas caso contrário não fará nenhuma conversão. Portanto, por exemplo, você não pode converter de shortpara int, como faria com um (int)elenco C # . Mas você pode converter de um IEnumerablepara um array, se sua IEnumerablevariável de objeto subjacente realmente for um Array. E, claro, você pode converter de Objectpara qualquer coisa, assumindo que o tipo de sua instância de objeto realmente está em algum lugar abaixo do seu tipo de conversão na árvore de herança.

Isso é desejável porque é muito mais rápido . Há menos conversão e verificação de tipo necessárias.

CType()é menos estrito do que o operador de conversão C #. Ele fará coisas que você simplesmente não pode fazer com uma (int)conversão de estilo simples , como converter uma string em um inteiro. Ele tem tanto poder quanto chamar Convert.To___()em C #, onde ___é o tipo de destino de seu elenco.

Isso é desejável porque é muito poderoso. No entanto, esse poder tem um custo de desempenho; não é tão rápido quanto o DirectCast()operador de elenco do C # porque pode precisar de muito trabalho para terminar o elenco. Geralmente, você deve preferir DirectCast()quando puder.

Por fim, você perdeu um operador de conversão:, TryCast()que é um análogo direto do asoperador do C # .


23
1 Eu diria que o rigor de DirectCasté outra vantagem. Se você cometer um erro, o compilador avisará imediatamente, mas com CTypeum erro pode causar um comportamento incorreto ocasional em tempo de execução - talvez em alguma máquina de usuário com configurações regionais diferentes.
MarkJ

1
Ótima resposta. Portanto, a fim de complexidade (pequeno a grande): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()seria correto?
lema de

3
@motto - fechar. As "funções" C <xyz> () devem ser movidas para o topo da lista, pois elas realmente são operadores em vez de funções, embora tenham semântica de função. Para aqueles tipos que os possuem, eles são muito próximos da conversão de C # (tipo), mas farão apenas um pouco mais de trabalho.
Joel Coehoorn

3
@MarkJ +1 pelo seu comentário, mas observe que DirectCasté estrito apenas com classes, não interfaces (porque você pode ter tipos COM - e talvez outros - que realmente implementam interfaces não definidas pela .GetInterfaceslista de Tipos .NET ).
Mark Hurd

2
@JoelCoehoorn +1, mas na verdade, TryCast()e asnão são exatamente os mesmos. TryCast()só funciona com tipos de referência, enquanto asfunciona com qualquer coisa que pode ser nula. Então int? icast = myNum as int?;vai funcionar bem, mas Dim icast as Integer? = TryCast(myNum, Integer?)vai dar um erro do compilador. Apenas mais uma diferença peculiar entre as duas línguas. lol
CptRobby

12

Com CTypevocê pode escrever algo assim Ctype("string",Integer). Mas com DirectCasta instrução acima daria erro em tempo de compilação.

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

0

DirectCasté mais restritivo do que CType.

Por exemplo, isso gerará um erro:

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

Ele também será mostrado no IDE do Visual Studio.

No entanto, isso não gera um erro:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.