Megosztás a következőn keresztül:


Adattípusok hibaelhárítása (Visual Basic)

Ez a lap felsorol néhány gyakori problémát, amelyek akkor fordulhatnak elő, ha belső adattípusokon hajt végre műveleteket.

Floating-Point kifejezések nem egyenrangúként

Ha lebegőpontos számokkal (egy adattípussal és dupla adattípussal) dolgozik, ne feledje, hogy ezek bináris törtekként vannak tárolva. Ez azt jelenti, hogy nem tartalmazhatnak pontos ábrázolást olyan mennyiségről, amely nem bináris tört (k / (2 ^ n) formában, ahol k és n egész számok. A 0,5 (= 1/2) és a 0,3125 (= 5/16) például pontos értékek, míg a 0,2 (= 1/5) és a 0,3 (= 3/10) csak közelítések lehetnek.

Emiatt a pontatlanság miatt nem támaszkodhat pontos eredményekre lebegőpontos értékek használatakor. Különösen két, elméletileg egyenlő érték némileg eltérő ábrázolásokkal rendelkezhet.

Lebegőpontos mennyiségek összehasonlítása
1. Számítsa ki a különbség abszolút értékét a Abs névtér osztályának System metódusávalMath.
2. Határozzon meg egy elfogadható maximális különbséget, hogy a két mennyiség gyakorlati szempontból egyenlő legyen, ha a különbségük nem nagyobb.
3. Hasonlítsa össze a különbség abszolút értékét az elfogadható különbségével.

Az alábbi példa két Double érték helytelen és helyes összehasonlítását mutatja be.

Dim oneThird As Double = 1.0 / 3.0
Dim pointThrees As Double = 0.333333333333333

' The following comparison does not indicate equality.
Dim exactlyEqual As Boolean = (oneThird = pointThrees)

' The following comparison indicates equality.
Dim closeEnough As Double = 0.000000000000001
Dim absoluteDifference As Double = Math.Abs(oneThird - pointThrees)
Dim practicallyEqual As Boolean = (absoluteDifference < closeEnough)

MsgBox("1.0 / 3.0 is represented as " & oneThird.ToString("G17") &
    vbCrLf & "0.333333333333333 is represented as " &
    pointThrees.ToString("G17") &
    vbCrLf & "Exact comparison generates " & CStr(exactlyEqual) &
    vbCrLf & "Acceptable difference comparison generates " &
    CStr(practicallyEqual))

Az előző példa a ToString struktúra metódusát Double használja, hogy nagyobb pontosságot adjon meg, mint a CStr kulcsszó. Az alapértelmezett érték 15 számjegy, de a "G17" formátum 17 számjegyre bővíti.

A Mod Operátor nem ad vissza pontos eredményt

A lebegőpontos tárolás pontatlansága miatt a Mod Operátor váratlan eredményt adhat vissza, ha az operandusok közül legalább az egyik lebegőpontos.

A Decimális adattípus nem használ lebegőpontos reprezentációt. Sok olyan szám, amely nem létezik Single , és Double pontosak Decimal (például 0,2 és 0,3). Bár az aritmetika lassabb Decimal , mint a lebegőpontos, érdemes lehet a teljesítménycsökkenést elérni a jobb pontosság érdekében.

Lebegőpontos mennyiségek egész számának megkeresése
1. Deklaráljuk a változókat .Decimal
2. A literáltípus karakter D használatával kényszerítse a literálokat arra Decimalaz esetre, ha az értékük túl nagy az Long adattípushoz.

Az alábbi példa a lebegőpontos operandusok lehetséges pontatlanságát mutatja be.

Dim two As Double = 2.0
Dim zeroPointTwo As Double = 0.2
Dim quotient As Double = two / zeroPointTwo
Dim doubleRemainder As Double = two Mod zeroPointTwo

MsgBox("2.0 is represented as " & two.ToString("G17") &
    vbCrLf & "0.2 is represented as " & zeroPointTwo.ToString("G17") &
    vbCrLf & "2.0 / 0.2 generates " & quotient.ToString("G17") &
    vbCrLf & "2.0 Mod 0.2 generates " &
    doubleRemainder.ToString("G17"))

Dim decimalRemainder As Decimal = 2D Mod 0.2D
MsgBox("2.0D Mod 0.2D generates " & CStr(decimalRemainder))

Az előző példa a ToString struktúra metódusát Double használja, hogy nagyobb pontosságot adjon meg, mint a CStr kulcsszó. Az alapértelmezett érték 15 számjegy, de a "G17" formátum 17 számjegyre bővíti.

Mivel zeroPointTwo a értéke Double, a 0,2 értéke végtelenül ismétlődő bináris tört, amelynek tárolt értéke 0,200000000000001. A 2,0-s mennyiség 9,999999999999999999999995 0,19999999999991 maradékával osztva.

A kifejezésben decimalRemaindera literális típusú karakter D mindkét operandust a értékre Decimalkényszeríti, a 0.2 pedig pontos ábrázolású. Ezért az Mod operátor a várt fennmaradó 0,0 értéket adja.

Vegye figyelembe, hogy a deklarálása decimalRemainderDecimalnem elegendő. A literálokat is a értékre kell kényszerítenie Decimal, különben alapértelmezés szerint használják Double őket, és decimalRemainder ugyanazt a pontatlan értéket kapja, mint a doubleRemainder.

A logikai típus nem konvertálható pontosan numerikus típussá

A logikai adattípus értékei nem számokként vannak tárolva, és a tárolt értékek nem egyenértékűek a számokkal. A korábbi verziókkal való kompatibilitás érdekében a Visual Basic konverziós kulcsszavakat (CType függvény, CBool, stb CInt.) biztosít a és a számtípusok közötti Boolean konvertáláshoz. Más nyelvek azonban néha másképp hajtják végre ezeket az átalakításokat, mint a .NET-keretrendszer metódusok.

Soha ne írjon olyan kódot, amely egyenértékű numerikus értékekre támaszkodik a és Falsea esetébenTrue. Amikor csak lehetséges, korlátoznia kell a változók használatát Boolean azokra a logikai értékekre, amelyekhez azokat tervezték. Ha össze kell kevernie és számértékeket kell használnia Boolean , győződjön meg arról, hogy ismeri a választott konverziós módszert.

Konvertálás a Visual Basicben

Ha a vagy CBool a konverziós kulcsszavakat használja numerikus CType adattípusokká Booleanvaló konvertálásához, a 0 leszFalse, és az összes többi érték lesz True. Ha az értékeket numerikus típussá alakítja Boolean át a konverziós kulcsszavak használatával, 0 lesz, False és True -1 lesz.

Átalakítás a keretrendszerben

A ToInt32 névtérben True lévő System osztály metódusa Convert +1 lesz.

Ha egy Boolean értéket numerikus adattípussá kell konvertálnia, ügyeljen arra, hogy melyik konverziós módszert használja.

Karakterkonstans fordítási hiba

Típuskarakterek hiányában a Visual Basic a literálok alapértelmezett adattípusait feltételezi. A karakterkonstansok alapértelmezett típusa – idézőjelek (" ") közé zárva – a következő String: .

Az String adattípus nem szélesedik ki a Char adattípusra. Ez azt jelenti, hogy ha literált szeretne hozzárendelni egy Char változóhoz, szűkítő konverziót kell végeznie, vagy a literált a Char típushoz kell kényszerítenie.

Karakterkonstans létrehozása változóhoz vagy állandóhoz való hozzárendeléshez
1. Deklarálja a változót vagy az állandót .Char
2. A karakterértéket idézőjelek közé kell tenni (" ").
3. Kövesse a záró dupla idézőjelet a literál típusú karakterrel C , hogy a literált a értékre kényszerítse Char. Ez akkor szükséges, ha a típus-ellenőrző kapcsoló (Option Strict Statement) a On, és ez minden esetben kívánatos.

Az alábbi példa egy változóhoz tartozó literál Char sikertelen és sikeres hozzárendelését mutatja be.

Dim charVar As Char
' The following statement attempts to convert a String literal to Char.
' Because Option Strict is On, it generates a compiler error.
charVar = "Z"
' The following statement succeeds because it specifies a Char literal.
charVar = "Z"c
' The following statement succeeds because it converts String to Char.
charVar = CChar("Z")

A szűkülő konverziók használata mindig fennáll, mert futásidőben meghiúsulhatnak. A konvertálás StringChar például meghiúsulhat, ha az String érték több karaktert tartalmaz. Ezért jobb programozni a C típus karaktert.

A sztringek konvertálása futásidőben meghiúsul

A sztring adattípusa nagyon kevés szélesítő konverzióban vesz részt. String csak önmagára, a Objectés a és a CharChar() ( Char tömbre) szélesedik ki String. Ennek az az oka, hogy String a változók és az állandók tartalmazhatnak olyan értékeket, amelyeket más adattípusok nem tartalmazhatnak.

Ha a típus-ellenőrző kapcsoló (Option Strict Statement) az On, a fordító nem engedélyezi az összes implicit szűkítési konverziót. Ide tartoznak a következők String: . A kód továbbra is használhat konverziós kulcsszavakat, például CStr és CType függvényt, amelyek a .NET-keretrendszer az átalakítás megkísérlésére irányítják.

Megjegyzés

A szűkítési-konvertálási hiba el van tiltva a gyűjtemény elemeiből For Each…Next a hurokvezérlő változóba való konvertáláskor. További információkért és példákért lásd a "Konvertálások szűkítése" szakaszt az Egyes... Következő utasítás.

A konvertálás elleni védelem szűkítése

A konverziók szűkítésének hátránya, hogy futásidőben meghiúsulhatnak. Ha például egy String változó az "Igaz" vagy a "Hamis" értéken kívül mást is tartalmaz, az nem konvertálható a értékre Boolean. Ha írásjeleket tartalmaz, a numerikus típusra való konvertálás sikertelen. Hacsak nem tudja, hogy a String változó mindig olyan értékeket tartalmaz, amelyeket a céltípus elfogadhat, ne próbálkozzon átalakítással.

Ha át kell konvertálnia String egy másik adattípusra, a legbiztonságosabb eljárás az, ha a megkísérelt átalakítást a Try... Fogás... Végül utasítás. Ez lehetővé teszi a futásidejű hibák kezelését.

Karaktertömbök

Char Egyetlen és egy elemtömb Char is ki van szélesedve.String Azonban String nem szélesedik ki a értékre Char(). Ha egy String értéket tömbre szeretne konvertálni Char , használhatja az ToCharArraySystem.String osztály metódusát.

Értelmetlen értékek

Az értékek általában String nem értelmezhetők más adattípusokban, és az átalakítás rendkívül mesterséges és veszélyes. Amikor csak lehetséges, korlátoznia kell a változók használatát String azokra a karaktersorozatokra, amelyekhez azokat tervezték. Soha ne írjon olyan kódot, amely más típusok egyenértékű értékeire támaszkodik.

Lásd még