IntegrovanΘ prost°edφ rubriky Visual Basic |
|||||||
|
ZaΦφnßme s VB
.NET |
||||||
┌vod do sv∞ta .NET (9. dφl) |
|||||||
╚asovß nßroΦnost (min): 45 |
ZaΦßteΦnφk |
PokroΦil² |
Profesionßl |
||||
|
|
|
|||||
|
Pou₧it² operaΦnφ systΘm : Hlavnφ v²vojov²
nßstroj : DalÜφ v²vojov² software : Jin² software : |
Windows 2000 SP3 Visual Basic .NET
2002 Äßdn² Äßdn² |
|||||
|
Milφ Φtenß°i,
v devßtΘ lekci naÜeho serißlu si povφme n∞co o konverznφch mechanizmech, kterΘ °φdφ konverzi hodnot prom∞nn²ch r∙zn²ch datov²ch typ∙ p°i rozmanit²ch p°φle₧itostech, nap°φklad p°i pou₧itφ p°i°azovacφho p°φkazu, nebo p°i prßci s parametry procedury. Dozvφte se, jak pracujφ implicitnφ a explicitnφ konverze a jakΘ funkce pou₧φt p°i konverzi hodnot prom∞nn²ch r∙zn²ch datov²ch typ∙.
Obsah |
Filosofie konverznφch mechanizm∙
Mßme-li mluvit o konverznφch mechanizmech, musφme si ze vÜeho nejd°φve vysv∞tlit jejich smysl, neboli skuteΦnost, proΦ je v∙bec pot°ebnΘ n∞jakΘ konverze pou₧φvat. Ka₧d² programovacφ jazyk obsahuje jistou mno₧inu vestav∞n²ch datov²ch typ∙, kterΘ m∙₧ou uchovßvat r∙znorodΘ hodnoty. Nejinak je tomu i ve Visual Basicu .NET. V p°edeÜl²ch dφlech serißlu jste mohli vid∞t p°ehled zßstupc∙ mnoha datov²ch typ∙, se kter²mi jsme pracovali v programovΘm k≤du. Ji₧ vφte, ₧e takzvanΘ celoΦφselnΘ datovΘ typy majφ mo₧nost pracovat s cel²mi Φφsly, a ₧e t°eba prom∞nnΘ datovΘho typu String dokß₧φ ulo₧it velmi dlouh² textov² °et∞zec. Ano, dosud nebylo zapot°ebφ jakkoliv se zmi≥ovat o konverzφch mezi prom∞nn²mi jednotliv²ch datov²ch typ∙, proto₧e tyto prom∞nnΘ p∙sobily vφce-mΘn∞ osamocen∞. Pokud ovÜem budeme chtφt, aby prom∞nnΘ zaΦaly mezi sebou mluvit, zßhy se pot°eba konverze hodnot dostavφ sama.
Pod pojmem konverze se ve vÜeobecnosti rozumφ jistß prom∞na zdrojov²ch dat na cφlovß data. Pracuje-li s grafick²m softwarem, je mo₧nΘ, ₧e Φasto p°evßdφte rastrovΘ obrßzky z jednoho formßtu do jinΘho. Pov∞zme, ₧e mßte za ·kol p°evΘst obrßzek, jen₧ je ulo₧en ve formßtu BMP, do podoby souboru JPG. P°esn∞ toto je nßzorn² p°φklad konverze. Jak tato konverze probφhß? Vskutku jednoduÜe, proto₧e vÜe za vßs vy°eÜφ vßÜ program pro editaci grafick²ch p°edloh. Program jednoduÜe vezme vstupnφ data (rastrov² obrßzek ve formßtu BMP) a tato data konvertuje do po₧adovanΘ cφlovΘ podoby (formßt JPG). Tuto situaci p°ibli₧uje obr. 1.
Obr. 1 û Nßzornß ukßzka konverze
jednoho grafickΘho formßtu do jinΘho
Situace, podobnΘ tΘ p°edchozφ, se vyskytujφ i v programovßnφ. Zde ovÜem nep∙jde p°φmo o zm∞nu formßtu grafickΘho obrßzku, n²br₧ o zm∞nu hodnot prom∞nn²ch r∙zn²ch datov²ch typ∙. Budeme-li postupovat analogicky, m∙₧eme tuto situaci op∞t graficky znßzornit (obr. 2).
Obr. 2 û Jedna z podob konverznφho procesu v programovßnφ
V uvedenΘm schΘmatu je ilustrovßna konverze hodnoty prom∞nnΘ celoΦφselnΘho datovΘho typu do prom∞nnΘ datovΘho typu String (mimochodem, jde o jeden z nejb∞₧n∞jÜφch typ∙ konverzφ).
Zajφmav∞jÜφ je ovÜem pohled na tento p°φklad po jednotliv²ch Φßstech. Pov∞zme, ₧e mßme deklarovanou prom∞nnou A datovΘho typu Integer, ve kterΘ je ulo₧ena jistß numerickß hodnota (°ekn∞me 100). Hodnota 100 p°edstavuje naÜe zdrojovß data, kterß vstupujφ do konverznφho mechanizmu. Jak jsme si ji₧ °ekli, v²sledkem prßce konverznφho mechanizmu jsou jistß cφlovß data. V naÜem p°φpad∞ majφ tato data podobu textovΘho °et∞zce, jen₧ obsahuje znaky ä1ô, ä0ô a ä0ô. Textov² °et∞zec je uschovßn v prom∞nnΘ B datovΘho typu String. Z ΦφselnΘ hodnoty 100 se tedy stane °et∞zec ä100ô, kter² m∙₧eme zobrazit t°eba v titulkovΘm pruhu hlavnφho okna aplikace. Nynφ se podφvejme, jak tento modelov² p°φklad znßzornit v programovΘm k≤du Visual Basicu .NET:
ááááááá Dim A As Integer = 100
ááááááá Dim
B As String
ááááááá B = A
ááááááá Me.Text = B áá
Nejpozoruhodn∞jÜφ je bezpochyby t°etφ °ßdek s p°i°azovacφm p°φkazem B = A. Algoritmus p°i°azovacφho p°φkazu mß p°ibli₧n∞ tuto podobu:
VÜimn∞te si, ₧e konverze byla v uvedenΘm p°φkladu provedena zcela automaticky a bez jakΘhokoliv zßsahu ze strany programßtora (vÜechnu prßci vykonal Visual Basic sßm). Konverzφm, kterΘ se uskuteΦ≥ujφ automaticky se °φkß implicitnφ konverze. Opakem implicitnφch konverzφ jsou konverze explicitnφ, p°i kter²ch musφ programßtor urΦit p°edm∞t a typ k²₧enΘ konverze. V dalÜφch Φßstφch se podφvßme na implicitnφ a explicitnφ konverze zblφzka.
Implicitnφ konverze
Implicitnφ konverze jsou realizovßny automaticky v₧dy, kdy₧ konverze m∙₧e b²t provedena bez toho, aby doÜlo ke ztrßt∞ dat. Visual Basic je zvyΦejn∞ natolik chytr², ₧e vφ, kdy implicitnφ konverze provΘst k plnΘ spokojenosti programßtora. N∞kterΘ varianty, kterΘ p°inßÜφ implicitnφ konverznφ mechanizmus, jsou shrnuty v tab. 1.
Tab. 1 û Implicitnφ konverze
Zdrojov² datov² typ |
Cφlov² datov² typ |
Byte |
Short, Integer,
Long, Single, Double, Decimal |
Short |
Integer, Long,
Single, Double, Decimal |
Integer |
Long, Single,
Double, Decimal |
Long |
Single, Double,
Decimal |
Single |
Double |
Char |
Integer, Long, Single,
Double, Decimal |
á
Uka₧me si dalÜφ p°φklad, v n∞m₧ se uplat≥uje mechanizmus implicitnφ konverze:
á
ááááááá Dim intPoΦet As Integer, lngPoΦet As Long
ááááááá intPoΦet = 100000
ááááááá lngPoΦet = intPoΦet
ááááááá MessageBox.Show("Hodnota prom∞nnΘ lngPoΦet je " & lngPoΦet)
Zde jsou deklarovanΘ dv∞ prom∞nnΘ: Prom∞nnß intPoΦet typu Integer a prom∞nnß lngPoΦet typu Long. Do prom∞nnΘ intPoΦet je p°i°azena hodnota 100000. Nßsledn∞ je hodnota integerovskΘ prom∞nnΘ p°i°azena do prom∞nnΘ lngPoΦet. Jeliko₧ ob∞ prom∞nnΘ jsou deklarovanΘ pou₧itφm r∙zn²ch datov²ch typ∙, dochßzφ v tomto p°φpad∞ k exekuci konverznφho mechanizmu. P°i bli₧Üφm pohledu by bylo mo₧nΘ °φci, ₧e jde o rozÜi°ujφcφ konverzi (widening conversion), proto₧e prom∞nnΘ datovΘho typu Long zabφrajφ vφce mφsta v pam∞ti a rovn∞₧ tak majφ daleko v∞tÜφ rozsah ve srovnßnφ s prom∞nn²mi datovΘho typu Integer. Zatφmco prom∞nnß intPoΦet obsazuje v pam∞ti 32 bit∙, u prom∞nnΘ lngPoΦet je to a₧ 64 bit∙ (obr. 3).
Obr. 3 û
Anatomie prom∞nn²ch intPoΦet a lngPoΦet
Z uvedenΘho jasn∞ vypl²vß, ₧e p°i konverzi hodnot prom∞nn²ch datovΘho typu Integer do prom∞nn²ch datovΘho typu Long nem∙₧e nikdy dojφt k ₧ßdnΘ ztrßt∞ dat, a proto je tato konverze zcela bezpeΦnß.
V poslednφm kroku je zobrazena hodnota prom∞nnΘ lngPoΦet v dialogovΘm okn∞ se zprßvou. AΦkoliv to mo₧nß nenφ na prvnφ pohled patrnΘ, i v tomto p°φkaze dochßzφ ke konverzi hodnoty. Za vÜechno m∙₧e operßtor z°et∞zenφ (&), jen₧ p°evede hodnotu prom∞nnΘ lngPoΦet na hodnotu datovΘho typu String. Takto vznikl² textov² °et∞zec je dßle spojen s textov²m °et∞zcem, jen₧ se nachßzφ nalevo od operßtoru &. Spojenφm, neboli z°et∞zenφm t∞chto dvou textov²ch °et∞zc∙ vznikß nov² °et∞zec, kter² je nßsledn∞ zobrazen v okn∞ se zprßvou.
Krom∞ rozÜi°ujφcφch konverzφ existujφ i opozitnφ konverze, p°i kter²ch dochßzφ ke konverzi hodnot do datovΘho typu s menÜφm rozsahem (narrowing conversions). Posu∩te tento fragment zdrojovΘho k≤du:
ááááááá Dim x As Byte, y As Short
ááááááá y = 200
ááááááá x = y
ááááááá MessageBox.Show("Hodnota prom∞nnΘ x je " & x)
Mßme zde deklarovanou prom∞nnou x datovΘho typu Byte a prom∞nnou y datovΘho typu Short. Do prom∞nnΘ y je p°i°azena hodnota 200. Dßle je hodnota prom∞nnΘ y p°i°azena do prom∞nnΘ x. SamotnΘmu p°i°azenφ p°edchßzφ konverze hodnoty prom∞nnΘ y do hodnoty datovΘho typu Byte (jde o datov² typ cφlovΘ prom∞nnΘ, kterß se nachßzφ na levΘ stran∞ p°i°azovacφho p°φkazu). VÜimn∞te si prosφm, ₧e i kdy₧ je rozsah prom∞nnΘ y v∞tÜφ ne₧ rozsah prom∞nnΘ x, prob∞hne toto p°i°azenφ bez problΘm∙. D∙vodem je skuteΦnost, ₧e prom∞nnß y obsahuje hodnotu (200), kterß se nachßzφ rovn∞₧ v intervalu p°φpustn²ch hodnot pro datov² typ Byte cφlovΘ prom∞nnΘ x. Co se ale stane, kdy₧ do prom∞nnΘ y p°i°adφme t°eba hodnotu 1000?
ááááááá Dim x As Byte, y As Short
ááááááá y = 1000
ááááááá x = y
ááá ááááMessageBox.Show("Hodnota prom∞nnΘ x je " & x)
V tomto p°φpad∞ bude vygenerovßna chyba
za b∞hu programu (obr. 4).
Obr. 4 û Chyba p°eteΦenφ
Jak se m∙₧eme dozv∞d∞t z chybovΘho hlßÜenφ, doÜlo k v²jimce System.OverflowException. Visual Basic nßm sd∞luje, ₧e p°i realizaci p°i°azovacφho p°φkazu doÜlo k p°ekroΦenφ hranic datovΘho typu Byte prom∞nnΘ x (jde o takzvanou chybu p°eteΦenφ rozsahu datovΘho typu) Proto₧e prom∞nnß datovΘho typu Byte m∙₧e pojmout pouze 256 hodnot z intervalu <0, 255>, nenφ jednoduÜe mo₧nΘ do tΘto prom∞nnΘ ulo₧it hodnotu 1000. Chybu m∙₧eme vy°eÜit v zßsad∞ dv∞ma zp∙soby:
ááááááá Dim x As Byte, y As Short
ááááááá y =
1000
ááááááá If y >= 0 And y
<= 255 Then
ááááááááááá x
= y
ááááááááááá
MessageBox.Show("Hodnota prom∞nnΘ x je " & x)
ááááááá Else
ááááááááááá
MessageBox.Show("Hodnota " & y & _
ááááááááááá
" nem∙₧e b²t ulo₧ena do prom∞nnΘ x.")
áááá End If
I kdy₧ jsme se jeÜt∞ v naÜem serißlu nev∞novali °φzenφ toku programu pomocφ rozhodovacφ programovacφ konstrukce If, nastßvß vhodnß chvφle na alespo≥ malou ukßzku. Rozhodovacφ konstrukce If testuje jistou podmφnku a v p°φpad∞, ₧e je tato podmφnka spln∞na (jinak °eΦeno, v²raz v podmφnce je vyhodnocen na pravdivostnφ hodnotu True), je proveden k≤d, jen₧ se nachßzφ za klφΦov²m slovem Then. Nenφ-li podmφnka spln∞na, je proveden programov² k≤d, jen₧ nßsleduje za nßv∞stφm Else. Celß konstrukce If je uzav°ena p°φkazem End If. Velmi d∙le₧it² je v²raz, kter² se testuje. V naÜem p°φpad∞ vypadß testovacφ v²raz nßsledovn∞:
y >= 0 And y <= 255
á
Tento v²raz nenφ jednoduch², n²br₧ kombinovan². Provßdφ testovßnφ prom∞nnΘ y pomocφ logickΘho operßtoru AND. V²raz je pravdiv², jestli₧e je prom∞nnß y rovna nebo v∞tÜφ ne₧ nula a souΦasn∞ menÜφ nebo rovna hodnot∞ 255. Je-li v²raz vyhodnocen na pravdivostnφ hodnotu True, je podmφnka spln∞na a proveden programov² k≤d, jen₧ nßsleduje na klφΦov²m slovem Then. ╪eΦeno jinak, obsahuje-li prom∞nnß y p°φpustnou hodnotu, kterou lze p°i°adit do prom∞nnΘ x, p°i°azovacφ p°φkaz bude vykonßn. Jinak bude zobrazeno dialogovΘ okno se zprßvou, ₧e p°i°azenφ nelze uskuteΦnit.
Prezentovanß technika zamezφ vzniku chyby za b∞hu programu a nebude zobrazeno ani ₧ßdnΘ chybovΘ hlßÜenφ. N∞kte°φ programßto°i tuto techniku znajφ pod nßzvem defenzivnφ programovßnφ, jeho₧ cφlem je p°edvφdßnφ v²skytu chyby a v p°φpad∞ vzniku chyby jejφ okam₧itΘ oÜet°enφ.
Explicitnφ konverze
Explicitnφ konverze jsou nevyhnutnΘ tehdy, kdy₧ hodnoty prom∞nn²ch r∙zn²ch datov²ch typ∙ nem∙₧ou b²t implicitn∞ konvertovßny. Ve skuteΦnosti nabφrß pot°eba explicitnφch konverzφ na v²znamu v p°φpad∞, ₧e p°i programovßnφ pou₧φvßte volbu Option Strict nastavenou na hodnotu On. Volba Option Strict:
|
Vytvß°enφ objekt∙ s pozdnφ vazbou (late-binding) probereme
n∞kdy p°φÜt∞, kdy se budeme uΦit o objektov∞ orientovanΘm programovßnφ (OOP).
|
Pokud budete chtφt konvertovat hodnoty prom∞nn²ch rozliΦn²ch datov²ch typ∙, budete muset pou₧φt funkci CType, p°φpadn∞ jinΘ konverznφ funkce, kterΘ jsou uvedeny v tab. 2.
Nßzev konverznφ funkce |
Nßvratovß hodnota konverznφ funkce |
CBool |
Boolean |
CByte |
Byte |
CChar |
Char |
CDate |
Date |
CDbl |
Double |
CDec |
Decimal |
CInt |
Integer |
CLng |
Long |
CObj |
Object |
CShort |
Short |
CSng |
Single |
CStr |
String |
áá
Uka₧me si nßzorn² p°φklad (p°itom p°edpoklßdßme, ₧e je aktivovßna volba Option Strict):
ááááááá Dim intV²sledek As Integer, str╪et∞zec As
String
ááááááá intV²sledek = Math.Max(5000,
10000)
ááááááá str╪et∞zec = CType(intV²sledek, String)
ááááááá Me.Text
= str╪et∞zec
Ve v²pisu zdrojovΘho k≤du jsou deklarovanΘ dv∞ prom∞nnΘ, intV²sledek datovΘho typu Integer a str╪et∞zec datovΘho typu String. Do prom∞nnΘ intV²sledek je ulo₧ena hodnota, kterou vracφ metoda Max t°φdy Math. Tato metoda p°ijφmß dv∞ celoΦφselnΘ hodnoty a vracφ tu z nich, kterß je v∞tÜφ. Metoda vracφ hodnotu v podob∞ celΘho Φφsla datovΘho typu Integer. NßÜ hlavnφ ·kol spoΦφvß v ulo₧enφ zφskanΘ nßvratovΘ hodnoty do prom∞nnΘ str╪et∞zec, kterß je zßstupcem datovΘho typu String. Jak jsme si ji₧ pov∞d∞li, aktivovanß volba Option Strict nedovoluje Visual Basicu provΘst implicitnφ konverzi celoΦφselnΘ hodnoty do podoby textovΘho °et∞zce. Proto musφme pou₧φt funkci CType v uvedenΘm tvaru.
Funkce CType pracuje se dv∞mi parametry. Prvnφm z nich je nßzev vstupnφ prom∞nnΘ (intV²sledek), kterß vstupuje do konverznφho procesu. Druh²m parametrem je nßzev datovΘho typu (String), do n∞ho₧ mß b²t vstupnφ prom∞nnß konvertovßna. V²sledkem prßce funkce je textov² °et∞zec, jen₧ je zobrazen v titulkovΘm pruhu okna formulß°e.
Analogicky by bylo mo₧nΘ p°edchßzejφcφ programovou ukßzku p°epsat pou₧itφm konverznφ funkce CStr:
ááááááá Dim intV²sledek As Integer, str╪et∞zec As
String
ááááááá intV²sledek = Math.Max(5000,
10000)
ááááááá str╪et∞zec = CStr(intV²sledek)
ááááááá Me.Text
= str╪et∞zec
DalÜφ p°φklad vypφÜe do titulkovΘho pruhu aplikace textov² °et∞zec äTrueô:
ááááááá Dim a As Short, b As Boolean
ááááááá a = 100
ááááááá b = CBool(a)
ááááááá Me.Text = CStr(b)
Konverze typu celoΦφselnß hodnota à pravdivostnφ hodnota datovΘho typu Boolean jsou mo₧nΘ a platφ, ₧e jakßkoliv nenulovß hodnota reprezentuje hodnotu True, zatφmco nula je konvertovßna na pravdivostnφ hodnotu False. Pokud byste cht∞li p°i°adit hodnotu prom∞nnΘ typu Boolean do celoΦφselnΘ prom∞nnΘ typu Integer, pravdivostnφ hodnotu True bude reprezentovat -1 a hodnotu False nula. Tuto konverzi p°edstavuje nßsledujφcφ fragment zdrojovΘho k≤du:
á
ááááááá Dim k As Integer, l As Boolean
ááááááá l = False
ááááááá k = CType(l,
Integer)
ááááááá Me.Text = CStr(k) ááá
Proto₧e prom∞nnß l obsahuje pravdivostnφ hodnotu False, bude po konverzi v titulkovΘm pruhu okna aplikace zobrazena nulovß hodnota.
Hodnoty prom∞nn²ch
datovΘho typu String a jejich konverze
Hodnoty prom∞nn²ch datovΘho typu String lze konvertovat do hodnot prom∞nn²ch numerick²ch datov²ch typ∙, samoz°ejm∞ za p°edpokladu, ₧e obsah textovΘho °et∞zce, jen₧ je ulo₧en v prom∞nnΘ typu String, m∙₧e b²t p°eveden do numerickΘ podoby. Prostudujte si tento p°φklad:
á
ááááááá Dim strText As String
ááááááá Dim
int╚φslo As Integer,
intOperace As Integer
ááááááá strText = "1440"
ááááááá int╚φslo = CType(strText, Integer)
ááááááá intOperace = (int╚φslo * 2) \
100 + 5
ááááááá Me.Text = CType(intOperace,
String)
Zde je hodnota ä1440ô prom∞nnΘ strText p°evedena do podoby celΘho Φφsla pomocφ konverznφ funkce CType. Takto zφskanß numerickß hodnota je dßle pou₧ita v matematickΘ operaci. Nakonec je hodnota prom∞nnΘ intOperace op∞t konvertovßna do hodnoty typu String a ulo₧ena do vlastnosti Text aktußlnφ instance formulß°e. Popravd∞, v²poΦetnφ vzorec se vßm m∙₧e zdßt pon∞kud slo₧it², a proto si jej probereme podrobn∞ji.
Matematick² v²raz:
áááááá intOperace = (int╚φslo * 2) \
100 + 5
á
mß nßsledujφcφ algoritmus v²poΦtu:
P°esn² pr∙b∞h v²poΦtu m∙₧ete sledovat na nßsledujφcφm schΘmatu (na ÜedΘm pozadφ jsou znßzorn∞nΘ operace s nejvyÜÜφ prioritou):
intOperace = (1440 * 2) \ 100 + 5
intOperace = 2880 \ 100 + 5
intOperace = 28 + 5
intOperace = 33
Jak jsme si ji₧ ukßzali, m∙₧ete hodnotu
celoΦφselnΘ prom∞nnΘ konvertovat i pomocφ operßtoru z°et∞zenφ (&).Tento program umφstφ do titulkovΘho pruhu textov² °et∞zec ä1 + 1 se
rovnß 2ô.
ááááááá Dim
strText As String
= "1 + 1 se rovnß "
ááááááá Dim
intHodnota As Integer
= 2
ááááááá Me.Text = strText & intHodnota
Pro konverzi textovΘho °et∞zce do podoby Φφsla s pohyblivou desetinnou Φßrkou m∙₧ete pou₧φt funkci Val. Parametr tΘto funkce p°ijφmß argument ve tvaru textovΘho °et∞zce a vracφ odpovφdajφcφ hodnotu v podob∞ Φφsla datovΘho typu Double.á
ááááááá Dim
strText As String
= "1200.250"
ááááááá Dim
dblHodnota As Double
ááááááá dblHodnota = Val(strText)
ááááááá Debug.WriteLine(dblHodnota)
á
Funkce Val p°evede hodnotu textovΘho °et∞zce na desetinnΘ Φφslo, kterΘ je nßsledn∞ zobrazeno v okn∞ Output. Metoda WriteLine t°φdy Debug se postarß o to, aby se hodnota prom∞nnΘ dblHodnota objevila v okn∞ Output.
|
Zobrazovßnφ hodnot prom∞nn²ch pomocφ metody WriteLine t°φdy Debug
je velmi u₧iteΦnΘ zejmΘna tehdy, kdy₧ mßte aktivovanou volbu Option Strict
a pot°ebujete okam₧it∞ zjistit hodnotu n∞jakΘ prom∞nnΘ, ale nechcete ji konvertovat
pomocφ funkce CType. |
Jßn Hanßk