Conversão de conversão e tipo de dados no VB.NET

Fundição é a processo de converter um tipo de dados para outro, por exemplo, de um tipo Inteiro para um tipo String. Algumas operações em VB.NET requerem tipos de dados específicos para funcionar. A transmissão cria o tipo que você precisa. O primeiro artigo desta série de duas partes, Conversão de transmissão e tipo de dados no VB.NET, apresenta a transmissão. Este artigo descreve os três operadores que você pode usar para transmitir VB.NET - DirectCast, CType e TryCast - e compara seu desempenho.

O desempenho é uma das grandes diferenças entre os três operadores de conversão, de acordo com a Microsoft e outros artigos. Por exemplo, a Microsoft geralmente tem o cuidado de alertar que "o DirectCast... pode fornecer um desempenho um pouco melhor que o CType ao converter para e do tipo de dados Objeto." (Enfase adicionada.)

Eu decidi escrever um código para verificar.

Mas primeiro uma palavra de cautela. Dan Appleman, um dos fundadores da editora de livros técnicos Apress e um técnico confiável guru, uma vez me disse que o desempenho de benchmarking é muito mais difícil de fazer corretamente do que a maioria das pessoas perceber. Existem fatores como desempenho da máquina, outros processos que podem estar em execução em paralelo, otimização como cache de memória ou otimização do compilador e erros nas suas suposições sobre o que o código é realmente fazendo. Nesses benchmarks, tentei eliminar erros de comparação "maçãs e laranjas" e todos os testes foram executados com a compilação do release. Mas ainda pode haver erros nesses resultados. Se você notar algum, entre em contato.

instagram viewer

Os três operadores de fundição são:

  • DirectCast
  • CType
  • TryCast

Na prática, você normalmente descobrirá que os requisitos do seu aplicativo determinarão qual operador você usa. O DirectCast e o TryCast têm requisitos muito restritos. Quando você usa o DirectCast, o tipo já deve ser conhecido. Embora o código ...

theString = DirectCast (theObject, String)

... será compilado com êxito se o objeto ainda não for uma sequência, o código gerará uma exceção de tempo de execução.

O TryCast é ainda mais restritivo porque não funciona em tipos de "valor", como Inteiro. (String é um tipo de referência. Para obter mais informações sobre tipos de valor e tipos de referência, consulte o primeiro artigo desta série.) Este código ...

theInteger = TryCast (theObject, Inteiro)

... nem compilará.

O TryCast é útil quando você não tem certeza com que tipo de objeto está trabalhando. Em vez de gerar um erro como o DirectCast, o TryCast simplesmente retorna Nothing. A prática normal é testar o Nothing após a execução do TryCast.

Somente CType (e os outros operadores "Convert", como CInt e CBool) converterão tipos que não têm um relacionamento de herança, como um número inteiro em uma string:

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

Isso funciona porque o CType usa "funções auxiliares" que não fazem parte do .NET CLR (Common Language Runtime) para executar essas conversões.

Mas lembre-se de que CType também lançará uma exceção se theString não contiver algo que possa ser convertido em um número inteiro. Se houver a possibilidade de a sequência não ser um número inteiro como este ...


Dim theString As String = "George"

... então nenhum operador de fundição funcionará. Mesmo o TryCast não funcionará com Inteiro porque é um tipo de valor. Em um caso como esse, você precisaria usar a verificação de validade, como o operador TypeOf, para verificar seus dados antes de tentar convertê-los.

A documentação da Microsoft para DirectCast menciona especificamente a conversão com um tipo de objeto. Foi isso que usei no meu primeiro teste de desempenho. Os testes começam na próxima página!

O DirectCast geralmente usa um tipo de objeto, e foi o que eu usei no meu primeiro teste de desempenho. Para incluir o TryCast no teste, também incluí um bloco If, pois quase todos os programas que usam o TryCast terão um. Nesse caso, no entanto, nunca será executado.

Aqui está o código que compara os três ao converter um objeto em uma string:

Escurecer o horário como novo cronômetro () Dim theString As String. Escureça o objeto como objeto = "An Object" Dim theIterations As Inteiro = CInt (iterações. Texto) * 1000000. ' Teste DirectCast. A Hora. Começar() Para i = 0 Para as iterações. theString = DirectCast (theObject, String) Próximo. A Hora. Pare() DirectCastTime. Texto = A Hora. Milissegundos decorridos. Para sequenciar. ' Teste CType. A Hora. Reiniciar() Para i Como Inteiro = 0 Para as Iterações. theString = CType (theObject, String) Próximo. A Hora. Pare() CTypeTime. Texto = A Hora. Milissegundos decorridos. Para sequenciar. ' Teste TryCast. A Hora. Reiniciar() Para i Como Inteiro = 0 Para as Iterações. theString = TryCast (theObject, String) Se theString não for nada então. MsgBox ("Isso nunca deve ser exibido") Fim se. Próximo. A Hora. Pare() TryCastTime. Texto = A Hora. Milissegundos decorridos. Para sequenciar.

Esse teste inicial parece mostrar que a Microsoft está certa no alvo. Aqui está o resultado. (Experiências com números maiores e menores de iterações, bem como testes repetidos sob diferentes condições, não mostraram diferenças significativas em relação a esse resultado.)


Clique aqui para exibir a ilustração

O DirectCast e o TryCast foram semelhantes em 323 e 356 milissegundos, mas o CType levou três vezes mais tempo em 1018 milissegundos. Ao converter tipos de referência como este, você paga pela flexibilidade do CType no desempenho.

Mas isso sempre funciona dessa maneira? O exemplo da Microsoft em sua página do DirectCast é útil principalmente para lhe dizer o que não trabalhar usando o DirectCast, não o que será. Aqui está o exemplo da Microsoft:

Dim q como objeto = 2,37. Dim i As Inteiro = CType (q, Inteiro) 'A conversão a seguir falha em tempo de execução. Dim j As Inteiro = DirectCast (q, Inteiro) Dim f como novo sistema. Janelas. Formulários. Formato. Dim c As System. Janelas. Formulários. Ao controle. 'A conversão a seguir tem êxito. c = DirectCast (f, Sistema. Janelas. Formulários. Ao controle)

Em outras palavras, você não pode use o DirectCast (ou TryCast, embora não o mencione aqui) para converter um tipo de objeto em um tipo inteiro, mas você pode use o DirectCast para converter um tipo de formulário em um tipo de controle.

Vamos verificar o desempenho do exemplo da Microsoft do que vai trabalhe com o DirectCast. Usando o mesmo modelo de código mostrado acima, substitua ...


c = DirectCast (f, Sistema. Janelas. Formulários. Ao controle)

... no código junto com substituições semelhantes para CType e TryCast. Os resultados são um pouco surpreendentes.


Clique aqui para exibir a ilustração

O DirectCast foi realmente a mais lenta das três opções em 145 milissegundos. CType é um pouco mais rápido em 127 milissegundos, mas o TryCast, incluindo um bloco If, é o mais rápido em 77 milissegundos. Eu também tentei escrever meus próprios objetos:


Classe ParentClass... Classe final. Classe ChildClass. Herda ParentClass... Classe final. 

Eu obtive resultados semelhantes. Parece que se você estiver não ao transmitir um tipo de objeto, você está melhor não usando o DirectCast.

instagram story viewer