Desenvolvimento - Visual Basic

Dez outras maneiras de se preparar para o VB.NET

Leve o seu código VB6 ao próximo nível: use estas técnicas para certificar-se de que os seus aplicativos são executados no mundo .NET.

por Billy Hollis



A maioria dos desenvolvedores de Visual Basic agora entende que a transição para o VB.NET será a maior feita até agora dentro do VB. Alinhar o VB ao .NET framework da Microsoft cria enormes vantagens: a completa orientação a objeto, o desempenho em paridade com qualquer outra linguagem .NET, novas capacidades para a Internet e a distribuição significantemente mais fácil, apenas para mostrar alguns pontos.

Mas estes avanços vêm a um custo: menos compatibilidade com qualquer versão anterior. Você vai querer entender como será a transição do VB6 e onde alguns problemas residem. Desde que a versão Beta 1 foi disponibilizada em novembro de 2000, eu tive a chance de fazer mais investigações sobre o VB.NET.

Não esqueça que você pode controlar as mudanças do VB6 para o VB.NET, usando a ferramenta de conversão oferecida. Uma versão anterior desta ferramenta é incluída na versão Beta 1, e espera-se mais funcionalidade nas futuras versões beta. Entretanto, a maioria dos artigos na lista abaixo não foi consertada pela versão atual da ferramenta de migração. Em alguns casos - não todos - a ferramenta de migração colocará um comentário “TODO:” no código para lhe mostrar aonde você precisa intervir manualmente.

1. Evite Strings de Extensão Fixa nas Estruturas

Strings de Extensão Fixa não são tipos de dados primitivos (suportado pelo compilador nativamente) em VB.NET como eles são no VB6. No .NET, uma classe de compatibilidade torna as strings de extensão fixa disponíveis para a maioria das situações, e você só precisa fazer uma mudança de declaração. Por exemplo, uma declaração em VB6 poderia se parecer com essa:

Listagem 1: Função com string de extensão fixa

Dim sTwelveCharacterID As String*12
No VB.NET, você precisa mudá-la para essa:
Dim sTwelveCharacterID As _	
	VB6.FixedLengthString(12)

O módulo precisa de uma instrução Imports, que se refere à compatibilidade de classes VB6, para que esta declaração funcione, de qualquer forma a variável - que agora é de fato um objeto - se comporta como um desenvolvedor VB6 esperaria.

Infelizmente, esta mudança apresenta um grande problema: um conceito chamado structures no VB.NET substitui os tipos definidos pelo usuário (UDTs - User-Defined Types) no VB6. As estruturas do VB.NET permitem somente os tipos de dados primitivos, o que significa que você não pode usar strings de extensão fixa nessas estruturas. Por exemplo, um UDT em VB6 poderia se parecer com esse:

Listagem 2: Comparação entre UDTs

Type TransferRecord
	RecID As Integer 
	Description As String*20
	Status As Boolean
End Type
Este é o equivalente mais próximo em VB.NET:
Structure TransferRecord
	Public RecID As Integer
	Public Description As String
	" Observe! Extensão da variável string!!
	Public Status As Boolean
End Structure

Usando esta estrutura, você fica completamente responsável pelo controle da extensão da parte Description da estrutura TransferRecord. Se a Description tiver que ter exatamente 20 caracteres, você precisa escrever o código para se certificar. Um modo de se fazer: faça a Description com 20 caracteres imediatamente após declarar um elemento de estrutura, e use a nova substituição para LSET (nomeada PadRight) para colocar os dados:

Listagem 3: Garantindo a extensão do string

Dim stcRecord As TransferRecord

stcRecord.Description = Space$(20)
" neste ponto, a string Description 
" tem exatamente 20 caracteres

" esse código ocorreria mais adiante abaixo
stcRecord.Description = _
	"Some description"
stcRecord.Description.PadRight(20)
" a string Description tem agora exatamente 
" 20 caracteres de extensão

Está confuso, mas é o único meio de tratar o assunto se você tiver de ter strings de extensão fixa numa estrutura. Evite usar strings de extensão fixa em UDTs no código atual, se você espera migrá-lo para o VB.NET. A ferramenta de migração não consegue consertar esse problema; você tem de fazê-lo manualmente.

2. Livre-se das Palavras-Chaves Obsoletas

O VB é descendente do QuickBASIC - um popular compilador DOS da Microsoft dos anos oitenta - que era descendente das primeiras implementações do BASIC. O VB sempre suportou os vários elementos de sintaxe obsoletos para conservar alguma compatibilidade com o QuickBASIC. Todos eles têm substituições mais modernas, e a maioria já não é mais usada, assim a Microsoft está se arriscando em retirá-los do VB. O VB.NET não suporta as palavras-chaves obsoletas: Gosub, On x GoTo... (GoTos computados), Let (como em, Let i = i + 1), VarPtr, ObjPtr, StrPtr, DefBool, DefByte, DefInt, DefLng, DefCur, DefSng, DefDbl, DefDec, DefDate, DefStr, DefObj, e DefVar.

Se algumas dessas são tão velhas que você nem mesmo sabe o que elas fazem, tudo bem - ignore-as. Mas se você estiver trabalhando com um código que usa qualquer uma dessas palavras-chaves, então você precisa mudar a lógica para as substituir - com exceção de Let, que você pode apagar.

A ferramenta de migração não lhe ajuda com nenhuma delas, exceto para marcá-las como não suportadas.

3. Remova o Objeto Implícito Instantiation

O VB6 oferece dois modos de declarar e criar uma instância de um objeto. Os desenvolvedores normalmente usam deste modo, porque a segunda linha cria imediatamente uma instância do objeto, eliminando a incerteza sobre quando o objeto é criado em instância:

Listagem 4: Instância de objeto em VB6 após declaração

Dim objSomeObject As MyClass
Set objSomeObject = New MyClass

O código funciona ainda no VB.NET com o “Set” removido desde o início da segunda linha. Os desenvolvedores também declaram e criam uma instância de um objeto em VB6 assim:

Listagem 5: Instância de objeto em VB6 junto com a declaração

Dim objSomeObject As New MyClass

" alguns códigos intervenientes vêm aqui ...

" Essa é a primeira referência a uma
" propriedade ou método do objeto.
objSomeObject.SomeProperty = _
	"A string value"

Neste caso, a primeira linha na verdade não cria uma instância do objeto. A primeira vez em que você se refere a um membro - propriedade ou método - do objeto, o VB6 cria uma instância do objeto antes de terminar a operação. Neste caso, para o VB6, a última linha no exemplo cria uma instância do objeto.

As regras mudam no VB.NET. Se você declara um objeto com Dim... As New..., então o instanciamento é imediato. Normalmente, essa mudança não importa. Porém, se o objeto Instantiation é prolongado, e você está contando com o objeto para não criar uma instância até que o código se refira a ele, o comportamento do programa muda. Neste caso, o usuário poderia notar a demora devido ao instanciamento num ponto diferente do programa. Se a lógica é suficientemente descuidada que o código interveniente está contando com o objeto que não está sendo criado em instância - digamos, se o objeto cria um arquivo, mas a lógica assume que o arquivo ainda não está lá - então o código não funciona corretamente no VB.NET.

No código VB6, evite o instanciamento implícito usando a primeira técnica de VB6 que eu descrevi, que funciona bem em VB6 e VB.NET. Entretanto, depois de migrar para o VB.NET, você poderia preferir a segunda forma na qual a declaração e o instanciamento ocorrem na mesma linha, por concisão.

4. Pare de Carregar o Formulário Implícito

Às vezes você carrega um formulário só para identificá-lo, nesse caso você tem um instanciamento implícito. Por exemplo, se você tem um formulário em um projeto nomeado frmCustomer, então no VB6 e versões anteriores esta linha faz com que o formulário carregue:

Listagem 6: Instanciamento implícito em VB6

frmCustomer.Show

Note que este tipo de comportamento não funciona com objetos baseados em módulos de classe no VB6 - somente com os formulários. Uma outra maneira do formulário ser carregado no VB6: declare uma variável form, crie uma instância, e exiba-o:

Listagem 7: Instanciamento explícito de form no VB6

dim frmNewCustomer As Form
set frmNewCustomer As New frmCustomer
frmNewCustomer.Show

Este segundo modo de exibir um formulário funciona bem no VB.NET, mas o primeiro modo não. Eis a razão: no VB.NET, um formulário é na verdade um módulo de classe que herda a classe WinForms para adquirir capacidades de formulário. Você deve criar uma instância de classe mantendo o formulário como qualquer outra classe.

Se você tem o hábito de carregar um formulário simplesmente para exibi-lo, precisa estar preparado para mudar os seus hábitos com o VB.NET; comece agora!

5. Remova as Ações de Processo das Condicionais

Suponha você tenha este código em VB6:

Listagem 8: Execução de método em estrutura condicional

If len(sID) = 0 And _
	(InitializeRecord(sNewID)) Then ...

O VB6 garante que ambas as partes da condição são avaliadas. Quer dizer, se o valor “len(sID) = 0 " é true ou false, o VB6 sempre executa a função InitializeRecord.

A maioria das outras linguagens não funciona deste modo por causa das implicações de lógica Booleana. Se você tem a condicional “A And B”, e sabe que A é false, então você também sabe que a condicional global é false, não importa o que seja B. A mesma situação aparece numa condicional Or. Se você tem “A Or B”, e sabe que A é true, então o resultado global é true, independente do valor de B.

Como conseqüência, a maioria das linguagens verifica a primeira condição Booleana, e avalia a segunda condição somente se afetar o resultado global. O VB.NET adota esta mesma convenção porque funciona com um runtime comum compartilhado por outras linguagens. Você não tem certeza se a segunda parte da condicional é avaliada no VB.NET. Se a primeira parte é false numa operação A, ou se a primeira parte é true numa operação Or, o VB.NET ignora a segunda parte. Nenhuma ação contida é realizada. Seja como for, você não deveria colocar em primeiro lugar as ações em condicionais. Esta codificação está malfeita, e às vezes parece que o VB.NET foi criado especificamente para punir os mal codificadores. Eis um modo melhor de escrever este código num formulário que funciona corretamente no VB6 e VB.NET:

Listagem 9: Correção do código da Listagem 8

Dim bRecordInitialized As Boolean
bRecordInitialized = InitializeRecord(sNewID)
If len(sID) = 0 And (bRecordInitialized) Then ...

6. Alterne Vinculação de Dados para ADO

Saiba que o VB.NET suporta a vinculação de dados para ActiveX Data Objects (ADO), e não para Data Access Objects (DAO) ou Remote Data Objects (RDO). Se você espera converter projetos com vinculação de dados, poderia querer converter a vinculação para ADO primeiro. A ferramenta de migração rovavelmente não o ajudará nesta conversão.

7. Utilize Constantes Intrínsecas Sempre que Possível

É uma boa convenção de programação utilizar as constantes intrínsecas do VB, sempre que possível.

Estas típicas linhas utilizam as constantes intrínsecas:

Listagem 10: Uso de constants intrínsecas do VB

Me.WindowState = vbNormal
MsgBox "Error!", vbCritical
bRecordLoaded = True

Em VB6, estas linhas são equivalentes às anteriores, no que diz respeito ao compilador:

Listagem 11: Uso equivalente ao das constants intrínsecas

Me.WindowState = 0
MsgBox "Error!", 16
bRecordLoaded = -1

A ferramenta de migração VB.NET não muda nenhuma das linhas em qualquer um destes exemplos. Porém, alguns dos valores de constantes intrínsecos subjacentes poderiam mudar. Por exemplo, a constante True no VB.NET não é -1; é + 1. Se você usa constantes intrínsecas, como no primeiro exemplo, você não notará a mudança e seu código continuará funcionando bem. Mas se habitualmente você usa os valores de constantes embutidos em código, como no segundo exemplo, seu código quebrará se qualquer um dos valores de constantes mudar.

8. Deixe de Escrever Páginas DHTML e WebClasses

A Microsoft declarou que a sua ferramenta de migração não suportará nenhuma página Dynamic HTML (DHTML). Os Web Forms substituem a funcionalidade das páginas DHTML no VB.NET. Converter as páginas DHTML existentes é um processo manual. Em muitos casos, por causa da diferença considerável entre DHTML e Web Forms, é mais eficaz recriar as páginas com o Web Forms, e possivelmente a lógica cortar e colar dos velhos formulários DHTML em VB6. A ferramenta de migração tenta converter WebClasses, mas o código precisa de um trabalho manual antes de funcionar no VB.NET.

Em qualquer circunstância de programação na qual você poderia esperar usar páginas DHTML ou WebClasses, usar Active Server Pages (ASP) que exige componentes COM é provavelmente uma escolha melhor para qualquer desenvolvimento novo. Os projetos feitos dessa maneira serão muito mais fáceis de converter à plataforma .NET. Lembre-se que migrar para o .NET não é uma decisão radical. É perfeitamente possível executar o VB6 e o VB.NET no mesmo sistema; eles não entram em conflito. Você pode continuar executando aplicativos antigos que contêm páginas DHTML e WebClasses no VB6, após converter seu novo desenvolvimento em VB.NET.

9. Entenda Herança e Conceitos de Objeto Relacionados

Herança completa e os conceitos relacionados, como substituição e construtores, são úteis, e o VB.NET suporta todos. Uma vez que você aprende a usar estes conceitos, perguntará a si mesmo como viveu sem eles (veja os artigos de Paul R. Reed Jr. e James Foxall em Fontes de Referência). Você pode obter vantagens começando a entender estes conceitos agora. Você pode simular alguns destes conceitos em VB hoje; muitos livros sobre VB discutem técnicas de simulação de herança (veja meu livro listado em Fontes de Referência). Estas técnicas são desajeitadas e poderiam ter problemas de desempenho, mas elas são úteis como ferramenta de aprendizagem e poderiam ser úteis se você tiver que começar um projeto agora em VB6, e que mais tarde será convertido em VB.NET.

10. Tenha Cuidado Onde Você Declara as Variáveis

Você pode se preparar para uma “surpresa” final no VB.NET. No VB6, não importa onde você declara uma variável numa rotina. Você pode declarar uma variável até mesmo dentro de um loop For ou de um bloco If, e estará disponível fora do loop ou do bloco. Eis um exemplo:

Listagem 12: Declaração de variável dentro de laço

Do
	Dim nTotal As Long
	nTotal = nTotal + 1 
Loop Until nTotal> 100 
MsgBox nTotal

Este código funciona bem em VB6, e a caixa de mensagem exibe o valor 101 depois de terminado o loop (veja Figura 1). Porém, as regras mudam no VB.NET que apresenta o conceito de escopo de bloco. Se você declarar uma variável dentro de um bloco, ela estará disponível somente dentro daquele bloco. O código precedente falha no VB.NET com um erro de sintaxe, porque nTotal é declarado dentro de bloco “Do loop”, mas a última linha usa nTotal e está fora do bloco (veja Figura 2). Na realidade, a cláusula Until na linha " Loop Until nTotal>100 " também é considerada fora do bloco.

Declarando Variáveis VB6.

Figura 1: Declarando Variáveis VB6.

No VB6, declarar uma variável dentro de um bloco não afeta seu escopo. Ainda é válido acessar a variável fora do bloco. Nessa tela, o código foi executado sem erros e gerou uma caixa de mensagem com o total de 101.

Declarando Variáveis VB.NET

Figura 2: Declarando Variáveis VB.NET.

No VB.NET, declarar uma variável dentro de um bloco faz com que a variável tenha um escopo de bloco. Mencionar a variável fora do bloco causa uma mensagem de erro que você pode verificar na Lista de Tarefa na parte de baixo, à esquerda da tela. Note que este é o mesmo código da Figura 1, exceto o nome padrão de comando do botão: em VB6 é Command 1, mas no VB.NET mudou para Button 1.

A solução para este problema: simplesmente declare as variáveis fora dos loops Do, For, While, e das instruções If, e desenvolva outro bloco. Muitas correntes adotam a convenção de que você declara todas as variáveis no topo da rotina, a qual cuida do problema.

Sobre o Autor

Billy Hollis é autor do Visual Basic 6: Design, Specification and Objects (Prentice Hall), e dá palestras em conferências como VBITS e Comdex. Ele é gerente geral da Oakwood Systems Group, consultores especializados em desenvolvimento de software com tecnologia Microsoft, e diretor regional da MSDN, Microsoft, em Nashville, Tennessee.

Read more: http://www.linhadecodigo.com.br/artigo/51/dez-outras-maneiras-de-se-preparar-para-o-vbnet.aspx#ixzz22LMeHKi7
Billy Hollis

Billy Hollis