Desenvolvimento - Visual Basic .NET

VB.NET: Estudo da linguagem - Parte 5

Este é mais um artigo da série de estudos sobre o Visual Basic .NET.

por Paulo Cesar Macedo



Importante:
Esse estudo foi uma compilação dos seguintes textos feita pelo autor:
MSDN Visual Studio 2002/2003 (tradução da fonte original do site da Microsoft)
Livro: Programando em Visual Basic de Michael J. Young.
Livro: Visual Basic for Windows de Steven Holzner.
Livro: Visualização e realidade virtual de Lee Adams.

2.10.1 – Estruturas de dados

As estruturas de dados é uma forma de combinar diferentes tipos de dados para criar uma única estrutura. Essa técnica é chamada de Tipo de Dados Compostos, pois permite criar tipos de dados personalizados que eram conhecidos como User Defined Type UDT nas versões do VB 6.0.

Entretanto, como as estruturas permitem criar além de tipos de dados fundamentais, também propriedades, métodos e eventos, as UDT foram aposentadas, e daqui por diante existirá somente as Estruturas de Dados.

Para criar uma estrutura, inicie com o Comando Structure e finalize com End Structure. Dentro desse bloco de código declare as variáveis normalmente. Exemplo :

Structure Empregado

Public Nome As String " Nome do empregado.

Public NomeFamília As String " Sobrenome da Família.

Public Telefone As Long " Telefone do empregado.

Private Salário As Decimal " Salário do empregado.

End Structure

No Exemplo acima, a estrutura foi criada com o nome de Empregado e possui variáveis públicas (Acesso a todos os blocos de código) e privadas (Acesso não permitido a outros blocos de código). Como opção, pode-se declarar uma estrutura como Public ou Private antes do comando Structure.

Depois de criar uma estrutura, deve-se criar uma variável e declará-la com o nome dessa estrutura, em seguida utilize as propriedades e métodos dessa estrutura. Exemplo

Dim MinhaVariável as Empregado

...

MinhaVariável.Nome = “Antonio”

2.10.2 – Matrizes (Arrays)

As Matrizes (Arrays) são séries de variáveis, objetos, elementos ou controles que possuem o mesmo nome e são diferenciados somente por um índice que os torna únicos para identificação. As variáveis de mesmo nome são identificadas pelo seu índice único, que vão desde o índice mais baixo também conhecido como LBound (lower bond) até o índice mais alto UBound (upper bond) , essas faixas permitem que o VB evite criar matrizes maiores que o necessário. Todos os elementos de uma matriz , devem ser de um único tipo de dados, entretanto se o tipo de dados for Object, é claro que os dados armazenados nesta matriz podem ser string, números, datas, objetos e etc.

  • Para se criar uma matriz pública, use o comando Public na seção de declaração.
  • Para se criar uma matriz a nível de módulo (module-level) , use o comando Private na seção de declaração.
  • Para se criar uma matriz local (procedure-level), use o comando Dim, Static dentro de um procedimento para declarar uma matriz.
  • Pode-se utilizar matrizes dentro de classes utilizando os comandos Protected, Friend, Public, Private e Dim.

As matrizes podem ser declaradas fixando os seus limites máximos com base na faixa do tipo de dados Long ( -2,147,483,648 até 2,147,483,647). Exemplos :

Dim MeuArray (14) as integer ‘ Matriz de 15 elementos

Dim MeuArray (2147483646) ‘ Máximo permitido

No exemplo acima, a matriz MeuArray foi declarada com no máximo 14 elementos, entretanto o limite inferior inclue o Zero (0), que é utilizado para efeito de contagem , portanto existe 15 slots para a matriz. A segunda declaração comporta o máximo de slots possível.

As matrizes podem ser alocadas automaticamente pelo VB, de modo que o desenvolvedor não precise determinar o limite máximo :

Dim MeuArray ( ) as integer ‘ Informa ao VB alocar automaticamente os limites.

O Exemplo acima não especifica os limites da matriz , apenas sujeita o VB alocá-lo automaticamente com parênteses ( ), essa matriz é conhecida como Matriz Dinâmica e o VB vai criar os limites até a faixa máxima do tipo de dados Long. Esse procedimento é utilizado, quando o desenvolvedor não sabe de antemão quais os limites da matriz.

Por outro lado , nos exemplos anteriores, a matriz foi alocada nos limites máximos, de forma que a matriz resultante é conhecida como Matriz Estática , e só pode ser utilizado quando o desenvolvedor tiver completa certeza dos limites da matriz a ser utilizada.

As matrizes são classificadas também pela quantidade de dimensões a saber :

Matrizes Unidimensionais – Que possuem apenas uma dimensão de valores mínimo e máximo . Como por exemplo :

Dim MeuArray (2) as string ‘Matriz unidimensional

Matrizes Multidimensionais – que possuem duas ou mais dimensões de valores mínimos ou máximos. Como por exemplo

Dim MeuArray (2,3,4) as string ‘Matriz tridimensional

Dim MeuArray ( , , ) as string ‘também pode ser escrito dessa forma

A quantidade de combinação de elementos de um matriz (Array) multidimiensional, é o resultado do produto dessas dimensões, assim no exemplo acima : 2 X 3 X 4 = 24 combinações de slots ou elementos. Assim o desenvolvedor pode fazer 60 combinações de elementos possíveis na matriz MeuArray. O VB aceita uma matriz com até 32 dimensões.

Para uma matriz multidimensional, a combinação de slots é complexo, a característica da combinação da matriz MeuArray (2,3,4) seria a seguinte :

10

30

50

70

90

110

130

150

170

190

210

230

20

40

60

80

100

120

140

160

180

200

220

240

O valor de MeuArray (1,1,1) = 10 ; o valor de MeuArray (2,3,4) = 240 de forma muito simples. Entretanto o valor de MeuArray (2,3,1) = 60, o valor de MeuArray (1,2,2) = 90. De forma geral tem-se :

Para se popular uma matriz, usa-se os índices apropriados juntamente com o tipo de dados corretamente, a forma recomendada pela Microsoft é utilizar um Loop para manipular e popular as matrizes.

Dim MeuArray (10, 10) as string

For i = 0 to 10

For j = 0 to 10

MeuArray ( i , j ) = “Olá “ & (i + j)

Next j

Next I

O Resultado final do loop será :

MeuArray ( 1, 1) = “Olá 2”

MeuArray ( 1, 2) = “Olá 3”

MeuArray (1, 3) = “Olá 4”

-

-

Etc...

Importante, as matrizes necessitam de muita memória para armazenar seus valores, e a medida que os valores limites aumentam , mais recursos do sistema é necessário. Além do mais, as matrizes multidimensionais construídas com base no tipo de dados Object, são vorazes consumidores de memória. As matrizes dinâmicas podem afetar o desempenho da execução do sistema.

O Vb oferece o comando ReDim para amenizar os custos de processamento e de memória de uma matriz dinâmica, de forma que quando usado, o VB muda os limites da matriz automaticamente com base em valores já encontrados, entretanto o comando ReDim só pode ser usado dentro de procedimentos (procedure-level) , sem especificar o tipo de dados. Portanto, quando se cria uma matriz com um número fixo, pode-se alterar mais tarde esse número, utilizando o comando ReDim.

Assim, quando declara-se uma matriz dinâmica na seção de módulo de um formulário, esta matriz pode ser redimensionada de dentro de uma procedure. A lógica de programação do desenvolvedor pode identificar os limites e dimensões da matriz, e em seguida redimensionar a matriz :

Dim Matrix1() As Integer

‘ procedimento abaixo, deveria calcular os limites da matriz

‘ e em seguida dimensionar Matrix1 com ReDim:

Sub CalcValuesNow ()

.

.

.

ReDim Matrix1(19, 29)

End Sub

No exemplo acima, a matriz Matrix1 foi declarada explicitamente de forma dinâmica com o tipo de dados numérica, e o procedimento CalcValueNow irá redimensionar os valores da matriz, para economizar recursos de memória e do sistema, utilizando o comando ReDim para alocar 20 e 30 slots multidimensionais. O trabalho do procedimento CalcValueNow é identificar os limites da matriz e redimensiona-los automaticamente.

Cada vez que Redim é acionado, os valores da matriz são limpos, assim os valores de tipos de dados variants são convertidos para vazios, os valores são zerados para os tipos de dados integers , os valores são limpos (strings de tamanho zero) para os tipos de dados string e os valores são convertidos para Nothing (nenhum objeto) para os arrays de objetos. A representação abaixo mostra como fica cada matriz após o uso de Redim:

Dim meu ( ) as string à Redim meu (1,1) à meu (1,1) = “”

Dim teu ( ) as variant à Redim teu (1,1) à teu (1,1) = Empty

Dim nosso ( ) as integer à Redim nosso (1,1) à nosso (1,1) = 0

Dim vosso ( ) as object à Redim vosso (1,1) à set vosso (1,1)= nothing

A única forma de reter esses valores , aproveitando os valores antigos já criados, e aumentando somente os slots para novos dados, utiliza-se o comando Preserve .

Redim Preserve Matrix1 (19 , 29)

De forma geral , esse comando é útil quando se deseja preparar a matriz para novos dados, mesmo que este esteja populado com valores anteriormente armazenados por procedimentos anteriores. Entretanto pode-se mudar apenas o último limite máximo (UBound) da última dimensão de uma matriz multidimensional, se tentarmos mudar um limite inferior (Lbound) ou de outra dimensão, um erro de run time vai ocorrer.

ReDim Preserve Matrix(19, UBound(Matrix, 2) + 1)

O código acima, pode ser usado, pois acrescenta a última dimensão da matriz Matrix um (1) slot a mais. Note que foi usado a função UBound para identificar o limite máximo da última dimensão (2).

ReDim Preserve Matrix(UBound(Matrix, 1) + 1, 10)

Entretanto o código acima, não pode ser utilizado, pois a tentativa de acrescentar mais um slot para a primeira dimensão, gera um erro de runtime.

Assim de forma resumida temos :

Pode-se atribuir um conteúdo de uma matriz para outra, de duas formas : A primeira copia-se slot por slot de cada matriz e atribui para outra matriz slot por slot, mas é mais eficiente utilizar a atribuição ( = ) para copiar uma matriz para outra :

Matriz A = Matriz B ‘Considerando que Matriz B já tenha dados

Obviamente, deve-se obedecer regras para efetuar cópias de variáveis, caso contrário podem gerar erros de compilação e de run-time :

As matrizes devem ter o mesmo tipo de dados, ou a variável que receber a cópia seja Object.

As matrizes devem ter o mesmo número de dimensões.

Os tipos de elementos de cada matriz devem ser compatíveis.

As matrizes só podem ser definidas com Base zero (0), isto é inicia-se no zero (0), assim um matriz do tipo “MinhaMatriz(5) “ possui 6 slots vazios , pois o limite inferior é zero.

1 – Utilizando Matrizes

Pode-se declarar uma matriz e em seguida atribuir o valor, ou declarar e atribuir (inicializar) o valor simultaneamente.

Exemplo 1 :

Dim MinhaVariável ( ) as single ‘ Declara uma variável dinâmica com unidimensional

MinhaVariável (1) = 3456 ‘Atribui um número ao primeiro slot

MinhaVariável (2) = 3457 ‘Atribui outro número ao segundo slot

Exemplo 2 :

Dim MinhaVariável ( ) as single = New single ( ) {3456 , 3457 } ‘Declara e inicializa os valores

No exemplo 1, foi criado a matriz MinhaVariável e atribuído os números separadamente, enquanto que no exemplo 2 foi criado a matriz MinhaVariável e atribuído os números simultaneamente.

Observe que no exemplo 2, a matriz é inicializada como parte da sua declaração, e portanto deve seguir as seguintes regras :

  • Use sempre o sinal de igual ( = ) seguido pela palavra chave New com o tipo de dados da matriz.
  • Finalize sempre com chaves { } a atribuição de valores.

Exemplo 3 :

Dim Meu ( ) as Byte = New Byte ( ) ‘ Declaração errada pois falta chaves { }

Dim Minha ( ) as Byte = New Byte ( ) { } ‘ Declaração correta

No exemplo acima as duas declarações foram feitas sem valores iniciais, mas somente a segunda declaração “Minha” é válida.

Exemplo 4:

Dim Nossa (1,1) as Short ‘Declaração de matriz Multidimensional

Nossa (0,0) = (5) ‘Atribui os valores

Nossa (0,1) = (6)

Nossa (1.0) = (7)

Nossa (1,1) = (8)

Exemplo 5 :

Dim Nossa ( , ) as Short = New Short ( , ) {{5,6},{7,8}} “Declara e inicializa uma _

matriz multidimensional

msgbox (Nossa (0,0)) ‘ exibe o valor 5

msgbox (Nossa (0,1)) ‘ exibe o valor 6

msgbox (Nossa (1,0)) ‘ exibe o valor 7 .........

No Exemplo 4 e 5, a matriz “Nossa” tem duas dimensões de zero até hum, com declarações e atribuições válidas, observe que no exemplo 5 a sintaxe é diferente.

Após a palavra chave New Short, é obrigatório incluir o número de vírgulas correspondentes a declarada na variável Nossa ( , ). Para atribuir os valores é obrigatório incluir chaves adicionais além de vírgulas { {5,6} , {8,8}}.

Exemplo 6 :

Dim Tua () () As Byte = {New Byte() {5, 6}, New Byte() {7, 8}}

Msgbox (Tua ( 0 ) ( 0 ) ) ‘ exibe o número 5

Msgbox ( Tua (0) ( 1) ) ‘ exibe o número 6

Msgbox ( Tua ( 1) ( 0) ) ‘ exibe o número 7

Msgbox ( Tua ( 1) (1 )) ‘ exibe o número 8

No exemplo 6, foi criado uma matriz contendo outra matriz. Este tipo de técnica é chamado de matriz não retangular ou recortada (jagged) e está disponível somente no VB .Net.

A matriz não retangular (matriz de matriz) tem sintaxe diferente de uma matriz multidimensional. No exemplo 6, a primeira matriz “Tua” foi inicializada com os valores 5 e 6 , enquanto que a segunda matriz foi inicializada com 7 e 8.

Assim para utilizar o primeiro elemento da primeira matriz usa-se ( 0 ) e ( 0 ), para utilizar o segundo elemento da primeira matriz usa-se (0) e (1). Para acessar o último elemento da última matriz do exemplo, usa-se (1) e (1).

Usa-se uma matriz de matriz quando o desenvolvedor deseja combinar matrizes mas não se deseja criar uma matriz bidimensional.

Exemplo 7

Dim Número(1) as integer

Dim Letra(1) as char

Número(0) =1 : Número(1) = 2

Letra(0) = “A” : Letra(1) = “B”

Dim TudoJunto(1) as Object

TudoJunto(0) = Número

TudoJunto(1) = Letra

Msgbox (TudoJunto(0)(0)) ‘ exibe 1

Msgbox (TudoJunto(0)(1)) ‘ exibe 2

Msgbox (TudoJunto(1)(0)) ‘ exibe A

Msgbox (TudoJunto(1)(1)) ‘ exibe B

No exemplo 7, criou-se uma matriz “TudoJunto” do tipo Objeto que aceita qualquer tipo de dados do sistema, além de duas matrizes de tipos de dados diferentes entre si.

Observe que não foi atribuído valores para TudoJunto, mas sim recebeu como atribuição as outras matrizes “Número” e “Letra”. Observe ainda, que este tipo de atribuição diminui o desempenho do aplicativo.

2 – Matriz é um elemento da classe System.Array

Como já foi visto nos tópicos anteriores, todo o tipo de dados fundamental é uma cópia de classes da tecnologia .Net Framework. Desta forma, as matrizes também herdam os recursos da classe System.Array, oferecendo seus próprios métodos.

Exemplo 8 :

Dim Meu(1) as integer = New Integer ( ) {4,5}

Msgbox (Meu.Rank) ‘ exibe o número 1 que equivale ao número de dimensões da matriz.

Msgbox (Meu.Length) ‘exibe o número 2 que equivale ao número de slots da matriz

Meu.Clear(Meu,0,1) ‘Limpa o slot 0 que contém o número 4

Msgbox (Meu(0)) ‘ exibe o número 0 como conseqüência da método Clear

No exemplo 8, foi declarado e inicializado a matriz “Meu”, em seguida foi invocado as Propriedades da classe .Net que está embutida na matriz Meu.

A Propriedade Rank retorna o número de dimensões da Matriz, enquanto que a Propriedade Length retorna o número de slots declarados na matriz. O Método Clear limpa o valor atribuído a um slot. Observe que para utilizar as funções-membros da classe é necessário fazer a referência completa à variável além do ponto . Meu.Rank.
Paulo Cesar Macedo

Paulo Cesar Macedo