Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az átalakítás az érték egyik típusról a másikra történő módosításának folyamata. A típusértékek Integer például átalakíthatók típusértékké Double, vagy a típus Derived értéke átalakítható típusértékké Base, feltéve, hogy BaseDerived az osztály és Derived az öröklött Baseérték is. Előfordulhat, hogy az átalakítások nem követelik meg magának az értéknek a módosítását (az utóbbi példához hasonlóan), vagy jelentős változásokat igényelhetnek az értékábrázolásban (mint az előző példában).
Az átalakítások szélesedhetnek vagy szűkülhetnek. A szélesítő átalakítás egy típusról egy másik típusra való átalakítás, amelynek értéktartománya legalább akkora, ha nem nagyobb, mint az eredeti típus értéktartománya. A konvertálások szélesítésének soha nem szabad meghiúsulnia. A szűkítő átalakítás egy típusról egy másik típusra történő átalakítás, amelynek értéktartománya kisebb az eredeti típus értéktartományánál, vagy nem kapcsolódik ahhoz, hogy az átalakítás során (például a konvertáláskor Integer ) fokozott figyelmet kelljen igényelni String. A konverziók szűkítése, amely adatvesztéssel járhat, meghiúsulhat.
Az identitásátalakítás (azaz egy típusból önmagába történő átalakítás) és az alapértelmezett értékátalakítás (azaz a konvertálás innen) Nothingminden típushoz meg van határozva.
Implicit és explicit konverziók
A konverziók lehetnek implicitek vagy explicitek. Az implicit konverziók speciális szintaxis nélkül történnek. Az alábbi példa egy érték implicit átalakítására Integer egy értékre Long :
Module Test
Sub Main()
Dim intValue As Integer = 123
Dim longValue As Long = intValue
Console.WriteLine(intValue & " = " & longValue)
End Sub
End Module
Az explicit átalakításokhoz viszont öntött operátorokra van szükség. Ha explicit konverziót próbál végrehajtani egy értéken egy öntött operátor nélkül, fordítási időt érintő hibát okoz. Az alábbi példa explicit átalakítást használ egy Long érték értékké alakításához Integer .
Module Test
Sub Main()
Dim longValue As Long = 134
Dim intValue As Integer = CInt(longValue)
Console.WriteLine(longValue & " = " & intValue)
End Sub
End Module
Az implicit konverziók halmaza az összeállítási környezettől és az Option Strict utasítástól függ. Szigorú szemantikák használata esetén csak a szélesítési konverziók fordulhatnak elő implicit módon. Ha megengedő szemantikát használ, az összes szélesítő és szűkítő konverzió (más szóval az összes konverzió) implicit módon is bekövetkezhet.
Logikai konverziók
Bár Boolean nem numerikus típus, a számtípusokra való és a számtípusokból való leszűkítési konverziói úgy néznek ki, mintha számba vett típus lenne. A literál True átalakítja a literálra 255 a következőhözByte: , 65535 for UShort, 429496729518446744073709551615 for UIntegerULong, , és a kifejezés -1 a SByte, Short, Integer, Long, Decimal, Singleés Double. A konstans False konstanssá 0alakul át. A nulla numerikus érték konstanssá Falsealakul. Az összes többi numerikus érték konstanssá Truealakul.
A logikai értékről sztringre való leszűkítést alkalmazunk, amely vagy a System.Boolean.TrueStringSystem.Boolean.FalseStringsztringre konvertálódik. A sztringet a következőkre StringBooleanis szűkíti: ha a sztring egyenlő TrueString volt vagy (a jelenlegi kultúrában a kis- és FalseString nagybetűk érzéketlenek), akkor a megfelelő értéket használja; ellenkező esetben numerikus típusként próbálja elemezni a sztringet (ha lehetséges, hexában vagy oktálisan, egyébként lebegőpontosként), és a fenti szabályokat használja, egyébként dob System.InvalidCastException.
Numerikus konverziók
Numerikus konverziók léteznek a típusokByteSByte, , , UShort, Short, IntegerUInteger, ULongLong, , DecimalSingle és Double, és az összes számbavételi típus között. Konvertáláskor a számba vett típusok úgy lesznek kezelve, mintha azok lennének a mögöttes típusok. Enumerált típussá való konvertáláskor a forrásértéknek nem kell megfelelnie a számbavételi típusban meghatározott értékek készletének. Például:
Enum Values
One
Two
Three
End Enum
Module Test
Sub Main()
Dim x As Integer = 5
' OK, even though there is no enumerated value for 5.
Dim y As Values = CType(x, Values)
End Sub
End Module
A numerikus konverziók futásidőben lesznek feldolgozva az alábbiak szerint:
Numerikus típusról szélesebb numerikus típusra való konvertáláshoz az érték egyszerűen a szélesebb típusra lesz konvertálva. A legközelebbire
LongULongIntegervagySingleDoubleDecimalértékre kerekített, illetve a legközelebbiDoubleSingleértékre kerekített konverziók.UIntegerBár ez az átalakítás a pontosság csökkenését okozhatja, soha nem okoz nagyságvesztést.Az integrál típusból egy másik integráltípusra, illetve az integrál típusra
SingleDoubleDecimalvaló átalakítás esetén az eredmény attól függ, hogy az egész szám túlcsordulása ellenőrzése be van-e kapcsolva:Egész szám túlcsordulás ellenőrzése esetén:
Ha a forrás egy integráltípus, az átalakítás akkor sikeres, ha a forrás argumentum a céltípus tartományán belül van. Az átalakítás kivételt
System.OverflowExceptioneredményez, ha a forrás argumentum kívül esik a céltípus tartományán.Ha a forrás
SingleDoubleértéke felfelé vagyDecimallefelé kerekítve van a legközelebbi integrálértékre, és ez az integrál érték lesz az átalakítás eredménye. Ha a forrásérték egyenlően közel áll két integrál értékhez, az érték arra az értékre lesz kerekítve, amelynek páros száma a legkisebb számjegypozícióban van. Ha az eredményként kapott integrálérték kívül esik a céltípus tartományán,System.OverflowExceptionkivétel keletkezik.
Ha nem ellenőrzi az egész szám túlcsordulését:
Ha a forrás egy integrált típus, az átalakítás mindig sikeres lesz, és egyszerűen a forrásérték legfontosabb bitjeinek elvetését jelenti.
Ha a forrás mindig sikeres, vagy
Decimalha a forrásSingleDoubleértéke mindig sikeres, és egyszerűen a forrásérték a legközelebbi integrálérték felé kerekítéséből áll. Ha a forrásérték egyenlően közel áll két integrál értékhez, az érték mindig arra az értékre lesz kerekítve, amelynek páros száma a legkisebb számjegypozícióban van.
DoubleSingleA konvertálás során az érték aDoublelegközelebbiSingleértékre lesz kerekítve. Ha azDoubleérték túl kicsi ahhoz, hogy egy értékkéntSinglelegyen jelölve, az eredmény pozitív nulla vagy negatív nulla lesz. Ha azDoubleérték túl nagy ahhoz, hogy egy értékkéntSinglelegyen jelölve, az eredmény pozitív végtelenné vagy negatív végtelenné válik. Ha azDoubleérték azNaN, akkor az eredmény isNaN.Ha a forrásértéket
DoubleDecimalSinglea program a 28. tizedesjegy után a legközelebbi számra kerekítve jeleníti megDecimal, akkor a forrásértéket ábrázolni kell, ha szükséges. Ha a forrásérték túl kicsi ahhoz, hogy az értéket jelöljeDecimal, az eredmény nullává válik. Ha a forrásérték végtelenNaNvagy túl nagy ahhoz, hogy egy értékkéntDecimallegyen jelölve,System.OverflowExceptionkivételt képez.DoubleSingleA konvertálás során az érték aDoublelegközelebbiSingleértékre lesz kerekítve. Ha azDoubleérték túl kicsi ahhoz, hogy egy értékkéntSinglelegyen jelölve, az eredmény pozitív nulla vagy negatív nulla lesz. Ha azDoubleérték túl nagy ahhoz, hogy egy értékkéntSinglelegyen jelölve, az eredmény pozitív végtelenné vagy negatív végtelenné válik. Ha azDoubleérték azNaN, akkor az eredmény isNaN.
Referenciakonvertálások
A referenciatípusok alaptípussá alakíthatók, és fordítva. Az alaptípusból származtatottabb típussá történő konvertálás csak futtatáskor sikeres, ha az átalakítandó érték null érték, maga a származtatott típus vagy egy származtatottabb típus.
Az osztály- és felülettípusok bármilyen felülettípusba be- és leírhatók. Egy típus és egy illesztőtípus közötti konvertálás csak akkor sikeres futásidőben, ha a tényleges típusok öröklési vagy megvalósítási kapcsolatban vannak. Mivel egy illesztőtípus mindig tartalmaz egy olyan típusú példányt, amelyből Objectszármazik, az illesztőtípus is mindig be- és lekontírozhat Object.
Jegyzet. Nem hiba átalakítani az NotInheritable osztályokat olyan felületekre és felületekről, amelyeket nem implementál, mert a COM-osztályokat képviselő osztályok olyan felületi implementációkkal rendelkezhetnek, amelyek a futtatásig nem ismertek.
Ha a referenciakonverzió futásidőben meghiúsul, kivétel System.InvalidCastException lép fel.
Referencia-variancia-konverziók
Az általános interfészek vagy meghatalmazottak olyan variánstípus-paraméterekkel rendelkezhetnek, amelyek lehetővé teszik a típus kompatibilis változatai közötti konverziót. Ezért futásidőben egy osztálytípusból vagy interfésztípusból egy olyan felülettípusra való átalakítás sikeres lesz, amely kompatibilis egy olyan felülettípussal, amelyet örököl vagy implementál. Hasonlóképpen, a delegálási típusok a variánskompatibilis delegálási típusokba is be- és leküldhetők. Például a meghatalmazott típusa
Delegate Function F(Of In A, Out R)(a As A) As R
a közötti átalakítást F(Of Object, Integer)F(Of String, Integer)lehetővé tenné. Ez azt is jelentheti, hogy a lekért meghatalmazott F biztonságosan használható meghatalmazottkéntF.StringObject A meghatalmazott meghívásakor a célmetódus objektumot vár, a sztring pedig objektum.
Az általános delegálási vagy felülettípus S(Of S1,...,Sn) azt mondja, hogy az általános felülettel vagy delegálási típussal T(Of T1,...,Tn)kompatibilis változat, ha:
SésTmindkettő ugyanabból az általános típusbólU(Of U1,...,Un)épül fel.Minden típusparaméterhez
Ux:Ha a típusparaméter variancia nélkül lett deklarálva, akkor
SxésTxugyanazzal a típussal kell rendelkeznie.Ha a típusparaméter deklarálva
Inlett, akkor szélesítő identitásnak, alapértelmezettnek, hivatkozásnak, tömbnek vagy típusparaméter-átalakításnakSxTxkell lennie.Ha a típusparaméter deklarálva
Outlett, akkor szélesítő identitásnak, alapértelmezettnek, hivatkozásnak, tömbnek vagy típusparaméter-átalakításnakTxSxkell lennie.
Ha egy osztályból általános felületre konvertálja a variánstípus paramétereit, ha az osztály egynél több variánskompatibilis felületet implementál, az átalakítás nem egyértelmű, ha nincs nem változatkonvertálás. Például:
Class Base
End Class
Class Derived1
Inherits Base
End Class
Class Derived2
Inherits Base
End Class
Class OneAndTwo
Implements IEnumerable(Of Derived1)
Implements IEnumerable(Of Derived2)
End Class
Class BaseAndOneAndTwo
Implements IEnumerable(Of Base)
Implements IEnumerable(Of Derived1)
Implements IEnumerable(Of Derived2)
End Class
Module Test
Sub Main()
' Error: conversion is ambiguous
Dim x As IEnumerable(Of Base) = New OneAndTwo()
' OK, will pick up the direct implementation of IEnumerable(Of Base)
Dim y as IEnumerable(Of Base) = New BaseAndOneAndTwo()
End Sub
End Module
Névtelen meghatalmazottkonvertálások
Ha egy lambda metódusként besorolt kifejezés olyan értékként van átsorolva egy olyan környezetben, Dim x = Function(a As Integer, b As Integer) a + bamelyben nincs céltípus (például ), vagy ha a céltípus nem delegált típus, az eredményül kapott kifejezés típusa egy névtelen delegálttípus, amely egyenértékű a lambda metódus aláírásával. Ez a névtelen delegálttípus bármilyen kompatibilis delegálttípusra konvertálható: a kompatibilis delegálttípus bármely olyan delegálttípus, amely egy delegáltlétrehozási kifejezéssel hozható létre paraméterként a névtelen delegálttípus Invoke metódusával. Például:
' Anonymous delegate type similar to Func(Of Object, Object, Object)
Dim x = Function(x, y) x + y
' OK because delegate type is compatible
Dim y As Func(Of Integer, Integer, Integer) = x
Vegye figyelembe, hogy a típusok System.Delegate nem System.MulticastDelegate tekinthetők delegált típusnak (annak ellenére, hogy minden delegált típus öröklődik tőlük). Azt is vegye figyelembe, hogy a névtelen delegált típusról kompatibilis delegált típusra való konvertálás nem referenciakonverzió.
Tömbkonvertálások
A tömbökön a hivatkozási típusok miatt definiált átalakítások mellett számos speciális átalakítás létezik a tömbökhöz.
Bármely két típus A esetében, és Bha mind a referenciatípusok, mind a típusparaméterek nem ismertek értéktípusok, és ha A hivatkozási, tömb- vagy típusparaméter-átalakítással Brendelkezik, akkor az átalakítás egy típustömbből A egy azonos rangú tömbbe B történik. Ezt a kapcsolatot tömb-kovariancia néven ismerjük. A tömb kovariancia különösen azt jelenti, hogy egy tömb olyan eleme, amelynek elemtípusa B valójában olyan tömb eleme lehet, amelynek elemtípusa A, feltéve, hogy mindkettő BA hivatkozási típus, és amely B hivatkozási átalakítással vagy tömbátalakítással Arendelkezik. Az alábbi példában a második meghívás F kivételt okoz System.ArrayTypeMismatchException , mert a tényleges elemtípus bStringnem Object:
Module Test
Sub F(ByRef x As Object)
End Sub
Sub Main()
Dim a(10) As Object
Dim b() As Object = New String(10) {}
F(a(0)) ' OK.
F(b(1)) ' Not allowed: System.ArrayTypeMismatchException.
End Sub
End Module
A tömbök kovariancia miatt a referencia típusú tömbök elemeihez való hozzárendelések futásidejű ellenőrzést tartalmaznak, amely biztosítja, hogy a tömbelemhez hozzárendelt érték ténylegesen engedélyezett típusú legyen.
Module Test
Sub Fill(array() As Object, index As Integer, count As Integer, _
value As Object)
Dim i As Integer
For i = index To (index + count) - 1
array(i) = value
Next i
End Sub
Sub Main()
Dim strings(100) As String
Fill(strings, 0, 101, "Undefined")
Fill(strings, 0, 10, Nothing)
Fill(strings, 91, 10, 0)
End Sub
End Module
Ebben a példában a metódushoz array(i)Fill való hozzárendelés implicit módon tartalmaz egy futásidejű ellenőrzést, amely biztosítja, hogy a változó valueNothing által hivatkozott objektum vagy olyan típusú példány legyen, amely kompatibilis a tömb arraytényleges elemtípusával. A metódusban Maina metódus Fill első két meghívása sikeres, de a harmadik meghívás kivételt System.ArrayTypeMismatchException okoz az első hozzárendelés array(i)végrehajtásakor. A kivétel azért fordul elő, mert egy Integer tömbben String nem tárolható.
Ha a tömbelem-típusok egyike olyan típusparaméter, amelynek típusa futásidőben értéktípusként jelenik meg, System.InvalidCastException kivétel jelenik meg. Például:
Module Test
Sub F(Of T As U, U)(x() As T)
Dim y() As U = x
End Sub
Sub Main()
' F will throw an exception because Integer() cannot be
' converted to Object()
F(New Integer() { 1, 2, 3 })
End Sub
End Module
Konverziók is léteznek egy számba vehető típusú tömb és a számbavételi típus alapjául szolgáló tömb vagy egy másik, azonos típusú enumerált típusú tömb között, feltéve, hogy a tömbök rangsora megegyezik.
Enum Color As Byte
Red
Green
Blue
End Enum
Module Test
Sub Main()
Dim a(10) As Color
Dim b() As Integer
Dim c() As Byte
b = a ' Error: Integer is not the underlying type of Color
c = a ' OK
a = c ' OK
End Sub
End Module
Ebben a példában a rendszer egy tömböt Color konvertál a mögöttes típusú tömbökre ByteColorés azok alapján. A tömbre Integervaló konvertálás azonban hiba lesz, mert Integer nem az alapul szolgáló típus Color.
A rang-1 típusú A() tömbök is tömbátalakítást hajtanak végre a gyűjteményi felület típusaira IList(Of B), IReadOnlyList(Of B)IReadOnlyCollection(Of B)ICollection(Of B)és IEnumerable(Of B) megtalálhatók System.Collections.Genericbenne, amennyiben az alábbiak egyike igaz:
-
AésBmind a referenciatípusok, mind a típusparaméterek nem ismertek értéktípusok; ésAszélesítő hivatkozással, tömb- vagy típusparaméter-átalakítássalBrendelkezik; vagy -
AésBmindkettő azonos alapul szolgáló típust sorol fel; vagy - az egyik
AszámbavételiBtípus, a másik pedig annak mögöttes típusa.
Az A típusú tömbök bármilyen ranggal is rendelkeznek, és tömbátalakítással is rendelkezik a nem általános gyűjteményfelület-típusokra IList, ICollection és IEnumerable a következő helyen System.Collectionstalálhatók: .
Az eredményül kapott felületeken iterálhat a metódusok közvetlen meghívásával GetEnumerator vagy használatávalFor Each. Az 1. helyezésű tömbök esetében általános vagy nem általános vagy nem általános formátumú IListICollectiontömbök esetén az elemek index alapján is lekérhetők. Általános vagy nem általános formátumúvá IListkonvertált 1. rangú tömbök esetén az elemek index szerint is beállíthatók, a futtatókörnyezeti tömbök kovariancia-ellenőrzései a fent leírtak szerint. Az összes többi felületi módszer viselkedését a VB nyelvi specifikációja nem határozza meg; az alapul szolgáló futtatókörnyezeten múlik.
Értéktípus-átalakítások
Az értéktípus-érték átalakítható az egyik alaphivatkozás-típusra, vagy egy olyan felülettípusra, amelyet egy boxing nevű folyamaton keresztül valósít meg. Ha egy értéktípus értéke be van jelölve, a rendszer a .NET-keretrendszer halomjára másolja az értéket onnan a helyről, ahol él. A rendszer ezután a halom ezen helyére mutató hivatkozást ad vissza, és egy referenciatípus-változóban tárolhatja. Ezt a hivatkozást az értéktípus dobozos példányának is nevezik. A dobozos példány szemantikája megegyezik a referenciatípussal értéktípus helyett.
A dobozos értéktípusok visszaalakulhatnak az eredeti értéktípusukra egy unboxing nevű folyamaton keresztül. Ha egy dobozos értéktípus nincs bejelölve, a rendszer az értéket a halomból egy változó helyre másolja. Ettől a ponttól kezdve úgy viselkedik, mintha értéktípus lenne. Egy értéktípus kicsomagolásakor az értéknek null értékűnek vagy értéktípus-példánynak kell lennie. Ellenkező esetben kivétel System.InvalidCastException történik. Ha az érték egy számozott típus példánya, akkor az érték a számozott típus alapjául szolgáló típushoz vagy egy másik, azonos alapul szolgáló típushoz tartozó számba vehető. A null érték úgy lesz kezelve, mintha a literál Nothinglenne.
A null értékű értéktípusok megfelelő támogatása érdekében az értéktípust System.Nullable(Of T) speciálisan kezeli a dobozolás és a kicsomagolás során. A típusértékek Nullable(Of T) dobozolása akkor eredményez dobozos típusú T értéket, ha az érték tulajdonsága HasValueTrue vagy értékeNothing, ha az érték tulajdonságaHasValue.False A típus T értékének leválasztása olyan példányt eredményez, Nullable(Of T) amelynek Value tulajdonsága Nullable(Of T) a dobozos érték, és amelynek HasValue a tulajdonsága .True Az érték Nothing bármelyikhez T megadhatóNullable(Of T), és olyan értéket eredményez, amelynek HasValue a tulajdonsága .False Mivel a dobozos értéktípusok hivatkozástípusokként viselkednek, több hivatkozás is létrehozható ugyanarra az értékre. A primitív és az enumerált típusok esetében ez irreleváns, mert az ilyen típusú példányok nem módosíthatók. Vagyis nem lehet módosítani az ilyen típusú dobozos példányokat, így nem lehet megfigyelni azt a tényt, hogy több hivatkozás is létezik ugyanarra az értékre.
A struktúrák viszont akkor lehetnek módosíthatók, ha a példányváltozói elérhetők, vagy ha a metódusai vagy tulajdonságai módosítják a példányváltozókat. Ha egy dobozos szerkezetre mutató hivatkozást használ a struktúra módosításához, akkor a dobozos szerkezetre mutató összes hivatkozás látni fogja a változást. Mivel ez az eredmény váratlan lehet, a rendszer automatikusan klónozza az egyik helyről egy másik dobozos értéktípusra másolt értéket Object ahelyett, hogy csak a hivatkozásaikat másolta volna. Például:
Class Class1
Public Value As Integer = 0
End Class
Structure Struct1
Public Value As Integer
End Structure
Module Test
Sub Main()
Dim val1 As Object = New Struct1()
Dim val2 As Object = val1
val2.Value = 123
Dim ref1 As Object = New Class1()
Dim ref2 As Object = ref1
ref2.Value = 123
Console.WriteLine("Values: " & val1.Value & ", " & val2.Value)
Console.WriteLine("Refs: " & ref1.Value & ", " & ref2.Value)
End Sub
End Module
A program kimenete:
Values: 0, 123
Refs: 123, 123
A helyi változó mezőhöz való hozzárendelése nem befolyásolja a helyi változó val2val1 mezőjét, mert amikor a mező hozzá lett rendelve Struct1val2, az érték másolatát készítették. Ezzel szemben a hozzárendelés ref2.Value = 123 hatással van arra az objektumra, amely mind a kettőre ref1ref2 hivatkozik.
Jegyzet. A struktúramásolás nem történik meg a beírt System.ValueType dobozos szerkezetek esetében, mivel nem lehet késői kötést végezni.System.ValueType
A szabály alól egyetlen kivétel van, amely szerint a program kimásolja a bekeretezett értéktípusokat a hozzárendeléshez. Ha egy dobozos értéktípusra mutató hivatkozás egy másik típuson belül van tárolva, a rendszer nem másolja át a belső hivatkozást. Például:
Structure Struct1
Public Value As Object
End Structure
Module Test
Sub Main()
Dim val1 As Struct1
Dim val2 As Struct1
val1.Value = New Struct1()
val1.Value.Value = 10
val2 = val1
val2.Value.Value = 123
Console.WriteLine("Values: " & val1.Value.Value & ", " & _
val2.Value.Value)
End Sub
End Module
A program kimenete:
Values: 123, 123
Ennek az az oka, hogy a belső dobozos érték nem lesz másolva az érték másolásakor. Így mindkettőhöz val1.Valueval2.Value ugyanahhoz a dobozos értéktípushoz kell hivatkoznia.
Jegyzet. Az a tény, hogy a belső dobozos értéktípusok nem másolódnak, a .NET-típusrendszer korlátozása – annak biztosítása érdekében, hogy minden belső dobozos értéktípus másolása tiltottan Object költséges legyen.
Ahogy korábban már említettük, a dobozos értéktípusok csak az eredeti típusukba csomagolhatók. A dobozos primitív típusokat azonban kifejezetten akkor kezelik, ha begépelik a következőt Object: . Bármely más primitív típussá alakíthatók át, amelybe konverziót végezhetnek. Például:
Module Test
Sub Main()
Dim o As Object = 5
Dim b As Byte = CByte(o) ' Legal
Console.WriteLine(b) ' Prints 5
End Sub
End Module
A dobozolt Integer értéket 5 általában nem sikerült kicsomagolódni egy Byte változóba. Mivel azonban IntegerByte primitív típusok, és konverzióval rendelkeznek, az átalakítás engedélyezett.
Fontos megjegyezni, hogy az értéktípus illesztővé alakítása eltér a felületre korlátozott általános argumentumtól. Ha korlátozott típusparaméteren (vagy meghívási metódusokon Object) fér hozzá az illesztőtagokhoz, a boxolás nem történik meg, mint amikor egy értéktípust illesztőre konvertálnak, és egy felülettagot érnek el. Tegyük fel például, hogy egy felület ICounter tartalmaz egy metódust Increment , amely egy érték módosítására használható. Ha ICounter kényszerként használják, a metódus implementációját a Increment rendszer a behívott változóra Increment való hivatkozással hívja meg, nem pedig dobozos másolattal:
Interface ICounter
Sub Increment()
ReadOnly Property Value() As Integer
End Interface
Structure Counter
Implements ICounter
Dim _value As Integer
Property Value() As Integer Implements ICounter.Value
Get
Return _value
End Get
End Property
Sub Increment() Implements ICounter.Increment
value += 1
End Sub
End Structure
Module Test
Sub Test(Of T As ICounter)(x As T)
Console.WriteLine(x.value)
x.Increment() ' Modify x
Console.WriteLine(x.value)
CType(x, ICounter).Increment() ' Modify boxed copy of x
Console.WriteLine(x.value)
End Sub
Sub Main()
Dim x As Counter
Test(x)
End Sub
End Module
Az első hívás, amely Increment módosítja a változó xértékét. Ez nem egyezik meg a második hívással Increment, amely módosítja a dobozos másolat xértékét. Így a program kimenete a következő:
0
1
1
Null értékű értéktípus konvertálása
Egy értéktípus T átalakítható a típus null értékű verziójára. T? A konvertálás kivételt T?TSystem.InvalidOperationException eredményez, ha a konvertált érték .Nothing Emellett egy típusra S való átalakítással rendelkezik, T? ha T belső átalakítással Srendelkezik.
S Ha pedig értéktípus, akkor a következő belső átalakítások léteznek a következők közöttT?:S?
Az azonos besorolású (szűkítő vagy szélesítő) besorolás átalakítása a helyről
T?a másikraS?.Az azonos besorolású (szűkítő vagy szélesítő) besorolás átalakítása a helyről
Ta másikraS?.A leszűkítő átalakítás a helyről a .-ra
S?T.
Egy belső szélesítési átalakítás például azért létezik Integer?Long? , mert belső szélesítési átalakítás létezik a következőhöz IntegerLong:
Dim i As Integer? = 10
Dim l As Long? = i
A konvertáláskor T?S?, ha az érték T? az Nothing, akkor a függvény értéke S? lesz Nothing. Az áttéréskor a rendszer kivételt System.InvalidCastException fog kivenniS, ha annak értéke vagy S? értéke T?Nothing.S?TT?
Az alapul szolgáló típus System.Nullable(Of T)viselkedése miatt, ha egy null értékű típus T? van bekeretezve, az eredmény egy dobozos típusú érték T, nem pedig egy dobozos típusú T?érték . Ezzel szemben, ha null értékű értékre T?bontja a jelölőnégyzetet, az érték be lesz burkolva System.Nullable(Of T), és Nothing null értékűre T?lesz csomagolva. Például:
Dim i1? As Integer = Nothing
Dim o1 As Object = i1
Console.WriteLine(o1 Is Nothing) ' Will print True
o1 = 10
i1 = CType(o1, Integer?)
Console.WriteLine(i1) ' Will print 10
Ennek a viselkedésnek az a mellékhatása, hogy egy null értékű értéktípus T? jelenik meg az összes interfész Timplementálásához, mivel az értéktípus illesztővé alakításához be kell jelölni a típust. Ennek eredményeként konvertálható az összes olyan felületre, T? amely T átalakítható. Fontos azonban megjegyezni, hogy egy null értékű értéktípus T? valójában nem valósítja meg az interfészeket T általános kényszerellenőrzés vagy tükrözés céljából. Például:
Interface I1
End Interface
Structure T1
Implements I1
...
End Structure
Module Test
Sub M1(Of T As I1)(ByVal x As T)
End Sub
Sub Main()
Dim x? As T1 = Nothing
Dim y As I1 = x ' Valid
M1(x) ' Error: x? does not satisfy I1 constraint
End Sub
End Module
Sztringkonvertálások
Eredményké String alakítás Char olyan sztringben, amelynek első karaktere a karakter értéke.
String
Char Az átalakítás eredménye egy olyan karakter, amelynek értéke a sztring első karaktere. Ha egy tömböt Char olyan sztringgé String alakít át, amelynek karakterei a tömb elemei. Eredménytömbté Char alakítás String olyan karakterekből álló tömbben, amelyek elemei a sztring karakterei.
Az és, , , SByte, UShortShort, DecimalULongDoubleLongDateSingleUIntegerIntegerés fordítva közötti pontos átalakítások String nem tartoznak a specifikáció hatókörébe, és egy részlet kivételével a megvalósítástól függenek. ByteBoolean A sztringkonvertálások mindig a futásidejű környezet aktuális kultúráját veszik figyelembe. Ezért futtatáskor kell végrehajtani őket.
Átalakítások szélesedése
A konvertálások bővítése soha nem túlcsordul, de a pontosság elvesztésével járhat. A következő átalakítások szélesítést eredményeznek:
Identitás/Alapértelmezett átalakítások
Egy típustól önmagáig.
A lambda metódushoz létrehozott névtelen delegálási típusból átsorolhat bármely azonos aláírású delegálttípusba.
A literáltól
Nothinga típusig.
Numerikus konverziók
Feladó
Byte,UShort,ShortUInteger,Integer,ULong,Long,Decimal, ,SinglevagyDouble.A
SByteaShort,Integer,Long,Decimal,SinglevagyDouble.A
UShortaUInteger,Integer,ULong,Long,Decimal,SinglevagyDouble.From
Short,Long, ,DecimalSingleorDouble.IntegerA
UInteger-rólULong-re,Long-re,Decimal-re,Single-re vagyDouble-re.From
Integer, ,DecimalSingleorDouble.LongA
ULongaDecimal,SinglevagyDouble.DecimalFromLong,SingleorDouble.Decimal-tólSingle-ig vagyDouble-ig.Single-tólDouble-ig.A literáltól
0az enumerált típusig. (Megjegyzés. A számbavételi típusra0való átalakítás a tesztelési jelzők egyszerűsítése érdekében szélesedik. Ha példáulValuesegy számbaOneadott típus értéke, akkor egy típusváltozótvValuesa következővel(v And Values.One) = 0tesztelhet: .)Az enumerált típustól a mögöttes numerikus típusig, vagy olyan numerikus típusig, amellyel az alapul szolgáló numerikus típus szélesíti az átalakítást.
A típus állandó kifejezésétől
ULong,Long,UInteger,IntegerUShort, ,Short,BytevagySByteegy szűkebb típusig, feltéve, hogy az állandó kifejezés értéke a céltípus tartományán belül van. (Megjegyzés. Az átalakítások aIntegerSingleDecimalUIntegerULongDoubleSingleLongSingleDoublepontosság csökkenését okozhatják, de soha nem okoznak nagyságvesztést. A többi számkonvertálás soha nem veszt el semmilyen információt.)
Referenciakonvertálások
Referenciatípustól alaptípusig.
Referenciatípustól egy interfésztípusig, feltéve, hogy a típus implementálja az interfészt vagy egy variánskompatibilis felületet.
Illesztőtípustól a
Object.Interfésztípustól a variánssal kompatibilis illesztőtípusig.
Delegált típustól a változatkompatibilis delegálási típusig. (Megjegyzés. Ezek a szabályok sok más referenciakonverziót is feltételeznek. A névtelen meghatalmazottak például olyan referenciatípusok, amelyektől
System.MulticastDelegateöröklődnek; a tömbtípusok olyan referenciatípusok, amelyektőlSystem.Arrayöröklődnek; a névtelen típusok olyan referenciatípusok, amelyek aSystem.Object.)
Névtelen meghatalmazottkonvertálások
- A lambda metódushoz létrehozott névtelen delegálási típusból bármilyen szélesebb delegálttípusba átsorolható.
Tömbkonvertálások
Elemtípusú tömbtípustól
Segy elemtípussalTerendelkező tömbtípusigT, feltéve, hogy az alábbiak mindegyike igaz:SeSésTcsak elemtípusban különbözik.TeMindkettőSereferenciatípus vagy típusparaméter, amely ismerten referenciatípus.Szélesítő hivatkozás, tömb vagy típusparaméter konvertálása létezik.
SeTe
Az enumerált elemtípusú tömbtípustól
Saz elemtípussalTerendelkező tömbtípusigT, feltéve, hogy az alábbiak mindegyike igaz:SeSésTcsak elemtípusban különbözik.Tea mögöttes típus.Se
Az 1. rangot tartalmazó tömbtípusból
S, amely számba vehető elemtípussalSerendelkezik ,System.Collections.Generic.IList(Of Te)a , ,IReadOnlyList(Of Te)ICollection(Of Te),IReadOnlyCollection(Of Te)ésIEnumerable(Of Te), feltéve, hogy az alábbiak egyike igaz:TeMindkettőSehivatkozási típus, vagy ismert típusparaméter, és szélesítő referencia-, tömb- vagy típusparaméter-átalakítás létezik a következőreSeTe: ; vagyTea mögöttes típus;SevagyTemegegyezik aSe
Értéktípus-átalakítások
Értéktípustól alaptípusig.
Értéktípustól a típus által implementálható illesztőtípusig.
Null értékű értéktípus konvertálása
TTípustól a típusigT?.Típusról típusra
T?S?, ahol a típusról a típusraTSvaló szélesítés történik.Típusról típusra
TS?, ahol a típusról a típusraTSvaló szélesítés történik.A típustól
T?a típusTáltal implementálható illesztőtípusig.
Sztringkonvertálások
Char-tólString-ig.Char()-tólString-ig.
Típusparaméter-konverziók
Típusparamétertől a .
ObjectA típusparamétertől az illesztőtípus-korlátozásig vagy az illesztőtípus-korlátozással kompatibilis bármely interfészvariánsig.
Típusparamétertől egy osztálykényszer által implementált felületig.
Típusparamétertől az osztálykényszer által implementált felülettel kompatibilis illesztővariánsig.
Típusparamétertől osztálykényszerig vagy az osztálykényszer alaptípusához.
A típusparamétertől
Ta típusparaméter-kényszerigTx, vagy bárminekTxvan egy szélesebb körű konvertálása.
Konverziók szűkítése
A szűkítő konverziók olyan konverziók, amelyek nem bizonyíthatók mindig sikeresnek, az ismert konverziók esetleg elveszítik az információkat, és a különböző típusú tartományok közötti konverziók eléggé különböznek a szűkítés jelölésétől. A következő konverziók leszűkítő konverziókként vannak besorolva:
Logikai konverziók
Feladó
Boolean,Byte,SByte,UShortShort,UInteger,Integer,ULong,Long,Decimal,Single, vagyDouble.From
Byte,SByte,UShort,Short,UIntegerInteger,ULong,Long,Decimal, ,Single, orDoubletoBoolean.
Numerikus konverziók
Byte-tólSByte-ig.A
SByteaByte,UShort,UIntegervagyULong.A
UShortaByte,SBytevagyShort.A
Short-rólByte-re,SByte-re,UShort-re,UInteger-re vagyULong-re.A
UInteger-rólByte-re,SByte-re,UShort-re,Short-re vagyInteger-re.A
IntegeraByte,SByte,UShort,Short,UIntegervagyULong.A
ULongaByte,SByte,UShort,Short,UInteger,IntegervagyLong.A
LongaByte,SByte,UShort,Short,UInteger,IntegervagyULong.DecimalaByte,SByte,UShort,Short,UInteger,Integer,ULongvagyLong.Feladó
Single,Byte,SByteUShort,Short,UInteger,Integer,ULong, ,LongvagyDecimal.Feladó
Double,Byte,SByte,UShortShort,UInteger,Integer,ULong,LongDecimalvagySingle.Numerikus típustól enumerált típusig.
Az enumerált típustól a numerikus típusig a mögöttes numerikus típusnak leszűkítő konverziója van.
Számbavételi típustól egy másik számbavételi típusig.
Referenciakonvertálások
Referenciatípustól egy származtatottabb típusig.
Osztálytípustól interfésztípusig, feltéve, hogy az osztálytípus nem implementálja az illesztőtípust vagy a vele kompatibilis felülettípus-változatot.
Felülettípustól osztálytípusig.
Egy illesztőtípustól egy másik illesztőtípusig, feltéve, hogy nincs öröklési kapcsolat a két típus között, és feltéve, hogy nem kompatibilisek a variánsokkal.
Névtelen meghatalmazottkonvertálások
- A lambda metódushoz létrehozott névtelen delegálási típusból bármilyen szűkebb delegálttípusba átsorolható.
Tömbkonvertálások
Elemtípusú tömbtípustól
Segy elemtípussalTerendelkező tömbtípusigT, feltéve, hogy az alábbiak mindegyike igaz:Se-
SésTcsak elemtípusban különbözik. -
TeMindkettőSereferenciatípus, vagy olyan típusparaméter, amelyről nem ismert, hogy értéktípus. - A szűkítési hivatkozás, tömb vagy típusparaméter konvertálása létezik a helyről
Sea másikraTe.
-
Elemtípusú
SetömbtípustólSegy számba vehető elemtípusúTetömbtípusigT, feltéve, hogy az alábbiak mindegyike igaz:-
SésTcsak elemtípusban különbözik. -
Seaz alapul szolgáló típusTe, vagy mindkettő különböző számbavételi típus, amely ugyanazt az alapul szolgáló típust használja.
-
Az 1. rangot tartalmazó tömbtípusból
S, amely számba vehető elemtípussalSerendelkezik,ICollection(Of Te)IReadOnlyCollection(Of Te)IList(Of Te)IReadOnlyList(Of Te)IEnumerable(Of Te)a következők valamelyike igaz:-
TeMindkettőSehivatkozási típus, vagy ismert típusparaméter, és egy szűkítő hivatkozás, tömb vagy típusparaméter konvertálása létezik a következőreSeTe: ; vagy -
Seaz alapul szolgáló típusTe, vagy mindkettő különböző számbavételi típus, amely ugyanazt az alapul szolgáló típust használja.
-
Értéktípus-átalakítások
Referenciatípustól egy származtatottabb értéktípusig.
Az illesztőtípustól az értéktípusig, feltéve, hogy az értéktípus implementálja a felület típusát.
Null értékű értéktípus konvertálása
T?Típustól típusigT.Típusról típusra
T?S?, ahol a típusról a típusraTSvaló leszűkítés történik.Típusról típusra
TS?, ahol a típusról a típusraTSvaló leszűkítés történik.Típusról típusra
S?T, ahol a típusról a típusraSTvaló átalakítás történik.
Sztringkonvertálások
String-tólChar-ig.String-tólChar()-ig.Feladó
StringésBooleanfeladóBooleanString.Átalakítások és
StringByte, ,SByte,UShortShort,UInteger,Integer,ULong,Long,Decimal,SinglevagyDouble.Feladó
StringésDatefeladóDateString.
Típusparaméter-konverziók
A típusparamétertől a típusparaméterig
Object.Típusparaméterről illesztőtípusra, feltéve, hogy a típusparaméter nincs az adott illesztőhöz korlátozva, vagy az adott interfészt megvalósító osztályhoz van korlátozva.
A felület típusától a típusparaméterig.
Típusparamétertől osztálykényszer származtatott típusig.
A típusparamétertől
Tbármiig, a típusparaméter-kényszernekTxleszűkítő konverziója van.
Típusparaméter-konverziók
A típusparaméterek konverzióit a kényszerek határozzák meg, ha vannak ilyenek. A típusparaméterek T mindig átalakíthatók önmagává, a felületi típusra és a típusra Object, illetve a felületre. Vegye figyelembe, hogy ha a típus T futtatáskor értéktípus, akkor az átkonvertálás ObjectT egy dobozos átalakítás lesz, és a kapcsolattípusból vagy felülettípusból ObjectT való konvertálás nem lesz megadva. Az osztálykényszerrel C rendelkező típusparaméter további átalakításokat határoz meg a típusparaméterről C az alaposztályokra, és fordítva. A típusparaméterek T típusparaméter-korlátozással Tx definiálják a Tx konvertálást, és minden átalakíthatóvá Tx .
Azok a tömbök, amelyek elemtípusa egy interfészkényszerrel I rendelkező típusparaméter, ugyanazokkal a kovariáns tömbkonverziókkal rendelkezik, mint egy olyan tömb, amelynek elemtípusa I, feltéve, hogy a típusparaméternek van vagy osztálykényszere is Class (mivel csak referenciatömbelem-típusok lehetnek kovarianták). Egy olyan tömb, amelynek elemtípusa osztálykényszerrel C rendelkező típusparaméter, ugyanazokkal a kovariantikus tömbkonvertálásokkal rendelkezik, mint egy olyan tömb, amelynek elemtípusa.C
A fenti konverziós szabályok nem teszik lehetővé a nem konvertált típusparaméterekből a nem interfész típusúakra való konvertálást, ami meglepő lehet. Ennek az az oka, hogy megakadályozzák az ilyen átalakítások szemantikáját. Vegyük például a következő deklarációt:
Class X(Of T)
Public Shared Function F(t As T) As Long
Return CLng(t) ' Error, explicit conversion not permitted
End Function
End Class
Ha a konvertálás TInteger engedélyezve lett volna, könnyen lehet, hogy ez X(Of Integer).F(7) vissza fog térni 7L. Ez azonban nem lenne így, mert a numerikus konverziókat csak akkor veszik figyelembe, ha a típusok ismerten numerikusak a fordításkor. A szemantika egyértelművé tétele érdekében a fenti példát inkább meg kell írni:
Class X(Of T)
Public Shared Function F(t As T) As Long
Return CLng(CObj(t)) ' OK, conversions permitted
End Function
End Class
User-Defined konverziók
A belső konverziók a nyelv által meghatározott konverziók (azaz a jelen specifikációban szerepelnek), míg a felhasználó által definiált konverziók az CType operátor túlterhelésével vannak definiálva. A típusok közötti konvertáláskor, ha nem alkalmazható belső átalakítás, akkor a rendszer figyelembe veszi a felhasználó által definiált átalakításokat. Ha a forrás- és céltípusokhoz a felhasználó által definiált konverzió a leginkább jellemző , akkor a rendszer a felhasználó által definiált konverziót használja. Ellenkező esetben fordítási idő hibát eredményez. A legspecifikusabb átalakítás az, amelynek operandusa "legközelebbi" a forrástípushoz, és amelynek eredménytípusa a céltípushoz "legközelebbi". A felhasználó által definiált átalakítás meghatározásakor a legspecifikusabb szélesítési átalakítás lesz használva; ha nincs a legkülönfélétebb átalakítás, akkor a legspecifikusabb leszűkítési átalakítás lesz használva. Ha nincs a legspecifikusabb leszűkítési konverzió, akkor az átalakítás nincs meghatározva, és fordítási időhiba lép fel.
A következő szakaszok a legspecifikusabb konverziók meghatározásának módját ismertetik. A következő kifejezéseket használják:
Ha egy belső szélesítési átalakítás létezik egy típusról A típusra B, és ha sem nem A , sem B interfészek, akkor Aazt magában foglaljaBés Bmagában foglaljaA.
A típusok halmazában a legfoglalóbb típus az a típus, amely a készlet összes többi típusát magában foglalja. Ha egyetlen típus sem foglalja magában az összes többi típust, akkor a készletnek nincs legfoglalóbb típusa. Intuitív értelemben a legfoglalóbb típus a "legnagyobb" típus a készletben – az egyik típus, amelyre a többi típus átalakítható szélesítő átalakítással.
A típusok halmazában a legelfoglaltabb típus az a típus, amelyet a készlet összes többi típusa magában foglal. Ha egyetlen típust sem foglal magában az összes többi típus, akkor a készletnek nincs a legfoglaltabb típusa. Intuitív értelemben a legelfoglaltabb típus a "legkisebb" típus a készletben – az egyik típus, amely egy szűkítő átalakítással konvertálható a többi típusra.
A felhasználó által definiált, felhasználó által definiált T?konverziók gyűjtésekor a rendszer ehelyett a felhasználó által T definiált konverziós operátorokat használja. Ha a konvertálandó típus szintén null értékű, akkor a rendszer feloldja a Tfelhasználó által definiált, csak nem null értékű értéktípusokat tartalmazó konverziós operátorokat. A átalakítási operátorok TS át lesznek emelve az átkonvertálásra S?T?, és szükség TT? esetén kiértékelik a felhasználó által definiált konverziós operátort ST, majd szükség esetén átalakítják SS?azt. Ha azonban a konvertált Nothingérték egy feloldott átalakítási operátor, akkor közvetlenül a következő típusú S?értékké Nothing alakul át: . Például:
Structure S
...
End Structure
Structure T
Public Shared Widening Operator CType(ByVal v As T) As S
...
End Operator
End Structure
Module Test
Sub Main()
Dim x As T?
Dim y As S?
y = x ' Legal: y is still null
x = New T()
y = x ' Legal: Converts from T to S
End Sub
End Module
A konverziók feloldásakor a felhasználó által definiált konverziós operátorok mindig előnyben részesülnek a feloldott konverziós operátorokkal szemben. Például:
Structure S
...
End Structure
Structure T
Public Shared Widening Operator CType(ByVal v As T) As S
...
End Operator
Public Shared Widening Operator CType(ByVal v As T?) As S?
...
End Operator
End Structure
Module Test
Sub Main()
Dim x As T?
Dim y As S?
y = x ' Calls user-defined conversion, not lifted conversion
End Sub
End Module
Futásidőben a felhasználó által definiált átalakítás kiértékelése legfeljebb három lépésből áll:
Először is az értéket a forrástípusból az operandus típusba konvertálja a rendszer, ha szükséges, belső átalakítással.
Ezután a rendszer meghívja a felhasználó által definiált konverziót.
Végül a felhasználó által definiált átalakítás eredménye szükség esetén belső átalakítással konvertálódik a céltípusra.
Fontos megjegyezni, hogy a felhasználó által definiált átalakítások kiértékelése soha nem fog egynél több felhasználó által meghatározott konverziós operátort bevonni.
A legspecifikusabb szélesítés konvertálása
A felhasználó által definiált legszűkebb konverziós operátor két típus között történő meghatározásához kövesse az alábbi lépéseket:
Először is a rendszer összegyűjti az összes jelölt konverziós operátort. A jelölt konverziós operátorok a forrástípus felhasználó által definiált szélesítő konverziós operátorai, valamint a céltípus felhasználó által definiált szélesítő konverziós operátorai.
Ezután az összes nem alkalmazható konverziós operátor el lesz távolítva a készletből. A konverziós operátor akkor alkalmazható a forrástípusra és a céltípusra, ha a forrástípustól az operandus típusig belső szélesítési átalakítási operátor van, és az operátor eredményétől a céltípusig belső szélesítési konverziós operátor van. Ha nincsenek alkalmazható konverziós operátorok, akkor nincs a legspecifikusabb szélesítési átalakítás.
Ezután meg kell határozni az alkalmazandó konverziós operátorok legspecifikusabb forrástípusát:
Ha a konvertálási operátorok bármelyike közvetlenül a forrástípusból konvertálódik, akkor a forrástípus a legspecifikusabb forrástípus.
Ellenkező esetben a legspecifikusabb forrástípus az átalakítási operátorok forrástípusainak kombinált készletében a legfoglaltabb típus. Ha nem található a legfoglaltabb típus, akkor nincs a legspecifikusabb szélesítési átalakítás.
Ezután meg kell határozni az alkalmazandó konverziós operátorok legspecifikusabb céltípusát:
Ha az átalakítási operátorok bármelyike közvetlenül a céltípusra konvertálódik, akkor a céltípus a legspecifikusabb céltípus.
Ellenkező esetben a legspecifikusabb céltípus a konverziós operátorok céltípusainak kombinált készletében a legfoglalóbb típus. Ha nem található a legfoglalóbb típus, akkor nincs a legspecifikusabb szélesítési átalakítás.
Ezután, ha pontosan egy konverziós operátor konvertálja a legspecifikusabb forrástípust a legspecifikusabb céltípusra, akkor ez a legspecifikusabb konverziós operátor. Ha egynél több ilyen operátor létezik, akkor nincs a legspecifikusabb szélesítési átalakítás.
A legspecifikusabb szűkítés konvertálása
A felhasználó által definiált legszűkebb konverziós operátor két típus között történő meghatározásához kövesse az alábbi lépéseket:
Először is a rendszer összegyűjti az összes jelölt konverziós operátort. A jelölt konverziós operátorok a forrástípus felhasználó által definiált konverziós operátorai, a céltípusban pedig a felhasználó által definiált konverziós operátorok.
Ezután az összes nem alkalmazható konverziós operátor el lesz távolítva a készletből. A konverziós operátor akkor alkalmazható a forrástípusra és a céltípusra, ha a forrástípustól az operandus típusig belső konverziós operátor van, és az operátor eredményétől a céltípusig belső konverziós operátor van. Ha nincsenek alkalmazható konverziós operátorok, akkor nincs a legspecifikusabb leszűkítési konverzió.
Ezután meg kell határozni az alkalmazandó konverziós operátorok legspecifikusabb forrástípusát:
Ha a konvertálási operátorok bármelyike közvetlenül a forrástípusból konvertálódik, akkor a forrástípus a legspecifikusabb forrástípus.
Ellenkező esetben, ha az átalakítási operátorok bármelyike a forrástípust magában foglaló típusokból konvertál, akkor a legspecifikusabb forrástípus az adott konverziós operátorok forrástípusainak együttes készletében a legfoglaltabb típus. Ha nem található a legfoglaltabb típus, akkor nincs a legspecifikusabb leszűkítési átalakítás.
Ellenkező esetben a legspecifikusabb forrástípus a leginkább felölelő típus az átalakítási operátorok forrástípusainak kombinált készletében. Ha nem található a legfoglalóbb típus, akkor nincs a legspecifikusabb leszűkítési átalakítás.
Ezután meg kell határozni az alkalmazandó konverziós operátorok legspecifikusabb céltípusát:
Ha az átalakítási operátorok bármelyike közvetlenül a céltípusra konvertálódik, akkor a céltípus a legspecifikusabb céltípus.
Ellenkező esetben, ha az átalakítási operátorok bármelyike a céltípus által lefedett típusokká alakul át, akkor a legspecifikusabb céltípus az adott konverziós operátorok forrástípusainak kombinált készletében a legfoglalóbb típus. Ha nem található a legfoglalóbb típus, akkor nincs a legspecifikusabb leszűkítési átalakítás.
Ellenkező esetben a legspecifikusabb céltípus a konverziós operátorok céltípusainak kombinált készletében a legelfoglaltabb típus. Ha nem található a legfoglaltabb típus, akkor nincs a legspecifikusabb leszűkítési átalakítás.
Ezután, ha pontosan egy konverziós operátor konvertálja a legspecifikusabb forrástípust a legspecifikusabb céltípusra, akkor ez a legspecifikusabb konverziós operátor. Ha egynél több ilyen operátor létezik, akkor nincs a legspecifikusabb leszűkítési átalakítás.
Natív konverziók
A konvertálások közül több natív konverzióként van besorolva, mert a .NET-keretrendszer natív módon támogatja őket. Ezek a konverziók olyan átalakítások, amelyek optimalizálhatók az és TryCast a DirectCast konverziós operátorok használatával, valamint más speciális viselkedésekkel. A natív konverzióként besorolt konverziók a következők: identitáskonverziók, alapértelmezett konverziók, referenciakonverziók, tömbkonverziók, értéktípus-átalakítások és típusparaméter-konverziók.
Domináns típus
A halmaz domináns típusának meghatározásához gyakran szükség van olyan helyzetekben, mint például a típuskövetkeztetés. Egy típuskészlet domináns típusát úgy határozzuk meg, hogy először eltávolítunk minden olyan típust, amelybe egy vagy több más típus nem rendelkezik implicit átalakítással. Ha ezen a ponton nincsenek típusok, akkor nincs domináns típus. A domináns típus a fennmaradó típusok közül a legfoglaltabb. Ha egynél több típus van, amely a legfoglaltabb, akkor nincs domináns típus.
Visual Basic language spec