You are on page 1of 13

.

NET - Usando tipos de dados corretamente


Muitas pessoas que decidem aprender uma linguagem de programao como
VB .NET ou C# geralmente no atentam para a importncia de compreender
os tipos de dados suportados e a forma correta de us-los. No caso do VB .NET
a ateno deveria ser redobrada visto que muitos esto migrando do VB5 ou
VB6 para o VB .NET e houve alteraes importantes que se no forem
consideradas podem dar muita dor de cabea no futuro.
Na tabela abaixo temos os tipos de dados do VB .NET:
Tipo de
dados

tipo .NET
Runtime

tamanh
o

intervalo

Boolean

System.Boolean

4 bytes

True ou False

Byte

System.Byte

1 byte

0 at 255 (sem sinal)

Char

System.Char

2 bytes

0 at 65535 (sem sinal)

Date

System.DateTime

8 bytes

Janeiro 1, 1 CE at Dezembro 31, 9999

Decimal

System.Decimal

12 bytes

+/-79,228,162,514,264,337,593,543,950,335
sem ponto decimal ; +/7.9228162514264337593543950335 com 28
casas a direita do decimal; o menor valor
diferente de zero algo em torno de
0.0000000000000000000000000001

Double

System.Double

8 bytes

-1.79769313486231E308 at
-4.94065645841247E-324 para valores
negativos; 4.94065645841247E-324 at
1.79769313486232E308 para valores positivos;

Integer

System.Int32

4 bytes

-2,147,483,648 at 2,147,483,647

Long

System.Int64

8 bytes

-9,223,372,036,854,775,808 at
9,223,372,036,854,775,807

Object

System.Object
(class)

4 bytes

Qualquer tipo pode ser armazenado.

Short

System.Int16

2 bytes

-32,768 at 32,767.

Single

System.Single

4 bytes

-3.402823E38 at -1.401298E-45 para valores


negativos; 1.401298E-45 at 3.402823E38 para
valores positivos;

String

System.String
(class)

10 bytes + At aproximadamente dois bilhes de


(2 *
caracteres Unicode.
tamanho
da string)

UserDefined

(herda de
Soma dos
System.ValueType) tamanhos

Cada membro da estrutura possui um intervalo


determinado pelo seu tipo de dados e

Type
(estrutura
)

dos seus
membros

independente dos intervalos dos demais


nmeros;

Eu vou simular um cenrio para mostrar que um pequeno detalhe pode


afetar , dependendo do ambiente, o comportamento esperado por um
programa.
Vamos supor que um programador trabalhando para uma instituio financeira
encarregado de criar um mdulo para tratar o saldo de operaes em um
determinado tipo de conta onde o cliente que possui um saldo positivo poder
programar amortizaes ou retiradas programadas at zerar o saldo.
Assim, se a conta possui um saldo de 100.00 ele poder efetuar
amortizaes/retiradas em parcelas mensais; por exemplo 10 parcelas de R$
10,00 at o saldo final ser igual a zero. Se o saldo for negativo o programa no
poder permitir retirada/amortizao. Com isso definido vamos ao cdigo que
o programador usou:
Usando o Visual Basic 2008 Express Edition vamos criar um projeto chamado
DoubleNet e no formulrio form1.vb vamos definir o seguinte leiaute:

Controles usados no
formulrio:

Button btnSimular Simular 10


Retiradas

TetBox txtSaldo Saldo Atual

TextBox txtParcela Valor Retirada

ListBox1 lstbResultado exibe o


resultado da
operao de
retirada;

definido o saldo
Atual e o valor da
parcela da retirada.
Para simular as
retiradas usado um
loop que ser
executado at que o
saldo for maior que
zero onde do valor do
saldo atual ser
subtrado o valor da
parcela; a cada
interao
incrementamos um
contador para saber o
nmero de retiradas
que foi efetuada.
Abaixo temos o trecho
de cdigo usado :
While seuSaldo > 0
seuSaldo -=
parcela

totalRetiradas +=

End While

Como estamos usando um ListBox para exibir o resultado o cdigo final


associado ao evento Click do boto - Simular 10 Retiradas - o seguinte:
Private Sub btnSimular_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
btnSimular.Click
'limpamos o controle ListBox e indicamos que estamos
usando um Double
lstbResultado.Items.Clear()
lstbResultado.Items.Add(" ---- Usando Double ----")
'obtemos o valor do saldo da parcela e definimos o valor
da varivel para contar as retiradas como sendo igual a
zero
Dim seuSaldo As Double = txtSaldo.Text
Dim totalRetiradas As Integer = 0
Dim parcela As Double = txtParcela.Text
'executamo o lao While enquando o saldo for maior que

zero
While seuSaldo > 0
seuSaldo -= parcela
totalRetiradas += 1
'exibimos o total de retiradas e o saldo no ListBox
lstbResultado.Items.Add("Retirou " & totalRetiradas & "
parcela")
lstbResultado.Items.Add("Saldo Atual: " & seuSaldo)
End While
'Aps encerrar o lao exibimos o total de retiradas
lstbResultado.Items.Add("-----------------")
lstbResultado.Items.Add("Voc retirou " & totalRetiradas &
" parcelas!")
End Sub
Vamos agora verificar se a lgica esta correta testando executando o
programa e fazendo alguns testes:
a-) Teste com saldo inicial igual a R$ 100,00 e parcela igual a 10,00:

O resultado confere e parece que tudo esta correto.


Vamos agora testar com um saldo atual igual a 150,50 e parcela de 15,05.
Estaremos esperando 10 retiradas de R$ 15,05 , correto ???
Executando o projeto iremos obter:

O resultado foi uma surpresa , no mesmo ???


Veja que na dcima retirada o saldo um valor muito pequeno mas diferente
de zero e assim foi permitido uma nova retirada. Uma catstrofe...
Mas qual o erro estamos cometendo ? Erro de lgica ? Erro de clculo ?
Nada disso o erro esta nas seguintes linhas de cdigo :

Dim seuSaldo As Double = txtSaldo.Text


Dim parcela As Double = txtParcela.Text
Mas Onde ????
O programador definiu as varivel como sendo do tipo Double que suporta
uma preciso numrica muito grande assim na dcima parcela retirada o saldo
um nmero muito pequeno ( 3,552713678805 elevado a -15) que devido a
preciso do tipo de dados usado levado em conta e computado.

Dessa forma o saldo no menor que zero permitindo assim uma nova
retirada.
Desta forma um pequeno detalhe poderia dar uma grande dor de cabea.
Um Double possui um tamanho de 8 bytes e atua no intervalo de :
-1.79769313486231E308 at -4.94065645841247E-324
Como resolver o problema no permitindo que a diferena seja
computada ?

Conselho : No VB .NET para efetuar clculos com valores monetrios


devemos usar o tipo Decimal.
No VB6 havia o tipo Currency que era usado para clculos financeiros mas no
VB .NET ele no existe e foi substitudo pelo tipo Decimal.
Se voc pretende continuar usando o VB6 a sugesto no usar o tipos de
dados Currency , use o tipo de dados Decimal no VB6 e no VB .NET use o tipo
de dados Decimal ou Long
Alm desta alterao temos abaixo uma tabela comparando o tipo de dados
usado no VB6 e o atualmente usado no VB .NET:

VB6

VB.NET

Comentrios

Integer

Short

16 bits

Long

Integer

32 bits

N/A

Long

64 bits

Variant

N/D

Use o novo tipo de dados Object

Currency N/D

Use o Decimal no VB6 ou Decimal ou Long no VB


.NET.

N/D

Disponvel no VB6(converter de Variant para


Decimal com a funo cDec.) Nativo no VB.NET

Decimal

String

String

O VB.NET no suporta strings de tamanho fixo.

Para usar o tipo de dados Decimal no VB6 voc pode declarar a varivel como
Variant e usar a funo cDec para convert-la para Decimal.

Conselho : A regra de ouro sempre declarar as variveis entes de us-las.


(Nunca use Option Explicit Off)
A opo Option Strict nova no VB.NET ; usando a opo Option Strict
evitamos os erros em tempo de execuo que se originam de converses
automticas de variveis.
Assim , na converso de uma varivel do tipo Int32 para o tipo Int16 ocorre
um estreitamento que pode ou no dar certo pois podem existir valores que
ao serem convertidos para int16 percam a preciso. Se voc trabalhar com a
opo Option Strict desativada , o VB vai deixar voc tentar , se der certo
muito bem se no der ....
Vamos a um exemplo :
O cdigo abaixo trabalha com a opo Option Strict desativada :
Option Strict Off
Private Sub Calculo(NumeroMaior
as Int32 , NumeroMenor as Int16)
Dim troca as int32
troca = NumeroMaior
NumeroMenor = troca
End Sub

O VB no vai reclamar e no indicar erro neste cdigo seu projeto vai rodar
bem at que voc tente fazer a converso de um nmero maior que 32.767 ,
ai sim vai ocorrer um erro na sua aplicao...
Se ativarmos a opo Option Strict o cdigo fica assim :
Option Strict On
Private Sub Calculo(NumeroMaior as
Int32 , NumeroMenor as Int16)
Dim troca as int32
troca = NumeroMaior
NumeroMenor = troca
if NumeroMaior >
NumeroMenor.Value then
MessageBox " Ateno !
Este nmero no suporta a
converso "

else
NumeroMenor =
Ctype(troca, Int16)
endif
End Sub
End Sub

Com a opo Option Strict ativada , a coisa muda de figura. Durante a fase de
projeto o VB.NET ir sublinhar o cdigo e ser gerado um erro em tempo de
compilao. O VB.NET no permite a voc usar o cdigo sem fazer a
modificao explcita ( manual ) . Voc avisado em tempo e pode ajustar o
seu cdigo.

Conselho : Use Option Explicit e Option Strict sempre ativas !


Tanto o VB.NET como C# so linguagens fortemente tipadas ( como Java), isto
significa que o compilador verifica por compatibilidades de tipos em tempo de
execuo em quase todos os casos , impedindo atribuies incompatveis ,
proibindo atribuies questionveis e fornecendo casts quando a
compatibilidade de um tipo puder ser determinada apenas em tempo de
execuo.
Algumas converses ocorrem automaticamente, sem voc ter que se
preocupar. Por padro no VB.NET o casting automtico quando voc atribui
objetos a variveis. Os objetos so ento convertidos fora para o tipo da
varivel. Este comportamento pode ser influenciado pelas declaraes:
- Option Strict On - (padro) - o casting restrito no automtico
- Option Strict Off - permite converses implcitas no seu cdigo
Para realizar um casting explcito (converso forada) podemos usar o
operador Ctype() ou DirectCast()
Dim Q As Object = 2.37
' Requer Option Strict Off.
Dim I As Integer = CType(Q, Integer)
' Funciona
Dim J As Integer = DirectCast(Q, Integer) ' Falha
Explicando: O tipo de Q em tempo de execuo Double .
Como voc pode converter Double para Integer , Ctype funciona.
DirectCast Falha porque o tipo de Q em tempo de execuo No
Integer.
Ambas as palavras chaves tomam uma expresso a ser convertida como
primeiro argumento e o tipo a converter como segundo argumento.
Se no houver uma converso definida entre o tipo de dados da expresso e o
tipo especificado a ser convertido tanto Ctype como DirectCast no iro
funcionar. Tanto Ctype como DirectCast lanam a exceo
InvalidCastException.

A funo CType opera em dois argumentos. A primeira a expresso a ser


convertido, e o segundo a classe tipo ou objeto de dados de destino.
Observe que o primeiro argumento deve ser uma expresso, no um tipo.
CType uma funo in-line, que significa que o cdigo compilado faz a
converso, com freqncia sem gerar um chamada de funo. Isso melhora o
desempenho.
Vejamos a seguir as principais funes de converso no VB .NET:

Fun
o

Descrio

Exemplo

Cbool

Converte para um Booleano


( False ou True). False ou 0 ser
definido como False. Retorna um
Boolean

Dim A, B, C As Integer
Dim Check As Boolean
A=5
B=5
Check = CBool(A = B) '
Check ser True.
' ...
C=0
Check = CBool(C) ' Check
ser False.

Cbyte

Dim MyDouble As Double


Converte para um Byte . Qualquer
Dim MyByte As Byte
valor maior que 255 ou valor
MyDouble = 125.5678
fracionrio ser perdido. Retorna
MyByte = CByte(MyDouble)
um Byte.
MyByte ser igual a

CChar

Converte para um Caracter .


Qualquer valor maior que 65,535
ser perdido e , se voc tentar
converter uma string somente o
primeiro caractere ser convertido.

Dim MyString As String


Dim MyChar As Char
MyString = "BCD" 'converte
s o primeiro caractere
MyChar = CChar(MyString) '
MyChar ser igual a "B".

Converte para um Date. Aceita


qualquer representao de data e
tempo.

Dim MyDateString,
MyTimeString As String
Dim MyDate, MyTime As Date
MyDateString = "February 12,
1969"
MyTimeString = "4:35:47 PM"
' ...
MyDate =
CDate(MyDateString) '
Converte p/ o tipo Date.
MyTime =
CDate(MyTimeString) '
Converte p/ o tipo Date.

CDate

CDbl

Converte para um Double.

CDec

Converte para um Decimal.

Dim MyDec As Decimal


Dim MyDouble As Double
MyDec = 234.456784D .
MyDouble = CDbl(MyDec *
8.2D * 0.01D) ' Converte
para Double
Dim MyDouble As Double
Dim MyDecimal As Decimal

'

MyDouble = 10000000.0587
MyDecimal =
CDec(MyDouble) ' Converte
para Decimal.

CInt

Dim MyDouble As Double


Converte para um inteiro. Valores
Dim MyInt As Integer
de -2,147,483,648 at
MyDouble = 2345.5678
2,147,483,647 . Fraes so
MyInt = CInt(MyDouble)
arredondadas.
MyInt ser igual a 2346.

CLng

Dim MyDbl1, MyDbl2 As


Double
Dim MyLong1, MyLong2 As
Converte para um Longo. Valores Long
-9,223,372,036,854,775,808 at MyDbl1 = 25427.45
9,223,372,036,854,775,807.
MyDbl2 = 25427.55
Fraes so arredondadas.
MyLong1 = CLng(MyDbl1)
MyLong1 conter 25427.
MyLong2 = CLng(MyDbl2)
MyLong2 conter 25428.

CSht

CStr

CSng

CObj
Ctype

'

'
'

Converte para um Short. Valores


de 32,768 a 32,767. Fraes so
arredondadas.

Dim MyByte as Byte


Dim MyShort as Short
MyByte = 100
MyShort = CShort(MyByte)
Converte para Short.

converte para um String. Se for


uma Data o retorno ser no
formato - Short Date.

Dim MyDouble As Double


Dim MyString As String
MyDouble = 437.324
MyString = CStr(MyDouble)
MyString ser igual a
"437.324".

Converte para um Single .


-3.402823E+38 at -1.401298E45 // 1.401298E-45 at
3.402823E+38

Dim MyDouble1, MyDouble2 As


Double
Dim MySingle1, MySingle2 As
Single
MyDouble1 = 75.3421105
MyDouble2 = 75.3421567
MySingle1 =
CSng(MyDouble1) '
MySingle1 ser igual a
75.34211.
MySingle2 =
CSng(MyDouble2) '
MySingle2 ser igual a
75.34216.

Converte para um objeto.

Converte para qualquer tipo de


dados. Sintaxe: Variavel =

Ctype( TipoVelho ,
NovoTipo)

'

'

Dim MyDouble As Double


Dim MyObject As Object
MyDouble = 2.7182818284
MyObject = CObj(MyDouble) '
MyDouble estar apontada
para MyObject.
Dim MyNumber As Long
Dim MyNewType As Single
MyNumber = 1000
MyNewType =
CType(MyNumber,Single) '

MyNewType igual a p/1000.0

Nota:
1. Se a expresso submetida a funo estiver fora do intervalo do tipo de
dados para o qual voc quer converter ocorrer um erro

2. Usamos estas funes para forar que o resultado de uma operao seja de

3.
4.

um tipo particular diferente do resultado padro. Assim usamos CDec para


forar para decimal em casos no qual a preciso simples, dupla ou um valor
inteiro normalmente iria ocorrer.
Se o valor fracionrio submetido for exatamente 0,5 , CInt e CLng iro
arredondar para o nmero par mais prximo. Assim 0,5 ser arredondado
para 0 e 1,5 ser arredondado para 2.
CDate reconhece o formato de datas de acordo com a configurao local do
sistema. Voc deve informar o dia , ms e ano na ordem correta de acordo
com a configurao local.

You might also like