Delen via


Conversies in Visual Basic

Conversie is het proces van het wijzigen van een waarde van het ene type naar het andere. Een waarde van het type Integer kan bijvoorbeeld worden geconverteerd naar een waarde van het type Double, of een waarde van het type Derived kan worden geconverteerd naar een waarde van het type Base, ervan uitgaande dat Base en Derived beide klassen en Derived overnemen van Base. Voor conversies is mogelijk niet vereist dat de waarde zelf wordt gewijzigd (zoals in het laatste voorbeeld) of dat er aanzienlijke wijzigingen in de waardeweergave nodig zijn (zoals in het vorige voorbeeld).

Conversies kunnen worden breder of beperkt. Een verbreidingsconversie is een conversie van een type naar een ander type waarvan het waardedomein minstens zo groot is als niet groter is dan het waardedomein van het oorspronkelijke type. Conversies voor widening mogen nooit mislukken. Een vermalingsconversie is een conversie van een type naar een ander type waarvan het waardedomein kleiner is dan het waardedomein van het oorspronkelijke type of voldoende niet-gerelateerd is dat er extra aandacht moet worden besteed bij het uitvoeren van de conversie (bijvoorbeeld bij het converteren van Integer naar String). Het beperken van conversies, wat kan leiden tot verlies van informatie, kan mislukken.

De identiteitsconversie (een conversie van een type naar zichzelf) en de standaardwaardeconversie (een conversie van Nothing) worden gedefinieerd voor alle typen.

Impliciete en expliciete conversies

Conversies kunnen impliciet of expliciet zijn. Impliciete conversies vinden plaats zonder speciale syntaxis. Hier volgt een voorbeeld van impliciete conversie van een Integer waarde naar een Long waarde:

Module Test
    Sub Main()
        Dim intValue As Integer = 123
        Dim longValue As Long = intValue

        Console.WriteLine(intValue & " = " & longValue)
    End Sub
End Module

Voor expliciete conversies zijn daarentegen cast-operators vereist. Als u probeert een expliciete conversie uit te voeren op een waarde zonder een cast-operator, treedt er een compilatietijdfout op. In het volgende voorbeeld wordt een expliciete conversie gebruikt om een Long waarde te converteren naar een Integer waarde.

Module Test
    Sub Main()
        Dim longValue As Long = 134
        Dim intValue As Integer = CInt(longValue)

        Console.WriteLine(longValue & " = " & intValue)
    End Sub
End Module

De set impliciete conversies is afhankelijk van de compilatieomgeving en de Option Strict instructie. Als er strikte semantiek wordt gebruikt, kunnen alleen verbreedingsconversies impliciet plaatsvinden. Als er permissieve semantiek wordt gebruikt, kunnen alle verbrekings- en narrowingconversies (met andere woorden, alle conversies) impliciet plaatsvinden.

Booleaanse conversies

Hoewel Boolean dit geen numeriek type is, heeft het wel beperkte conversies van en naar de numerieke typen alsof het een geïnventariseerd type is. De letterlijke True tekst wordt omgezet in de letterlijke voor 255Byte, 65535 voor , 4294967295 voor UIntegerUShort, 18446744073709551615 en ULongin de expressie -1 voor SByte, Short, Integer, Long, , Decimal, , en .DoubleSingle De letterlijke False wordt geconverteerd naar de letterlijke .0 Een nul numerieke waarde wordt geconverteerd naar de letterlijke waarde False. Alle andere numerieke waarden worden geconverteerd naar de letterlijke waarde True.

Er is een vermalingsconversie van Booleaanse waarde naar Tekenreeks, die wordt geconverteerd naar of System.Boolean.TrueStringSystem.Boolean.FalseString. Er is ook een vermalingsconversie van String : Booleanals de tekenreeks gelijk is aan TrueString of FalseString (in de huidige cultuur, hoofdlettergevoelig) dan wordt de juiste waarde gebruikt; anders wordt geprobeerd de tekenreeks te parseren System.InvalidCastExceptionals een numeriek type (in hex of octaal indien mogelijk, anders als een float) en de bovenstaande regels te gebruiken; anders wordt deze gegenereerd.

Numerieke conversies

Er bestaan numerieke conversies tussen de typen Byte, , UShortSByte, , Short, UInteger, ULongIntegerDecimalLongen Single , en Doublealle opgesomde typen. Wanneer ze worden geconverteerd, worden opgesomde typen behandeld alsof ze hun onderliggende typen zijn. Bij het converteren naar een geïnventariseerd type is de bronwaarde niet vereist om te voldoen aan de set waarden die zijn gedefinieerd in het geïnventariseerd type. Voorbeeld:

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

Numerieke conversies worden als volgt tijdens runtime verwerkt:

  • Voor een conversie van een numeriek type naar een breder numeriek type wordt de waarde gewoon geconverteerd naar het bredere type. Conversies vanUInteger, Integer, , ULong, of Longnaar Single of DoubleDecimal worden afgerond op het dichtstbijzijnde of Double de dichtstbijzijnde Single waarde. Hoewel deze conversie een verlies van precisie kan veroorzaken, zal het nooit een verlies van grootte veroorzaken.

  • Voor een conversie van een integraal type naar een ander integraal type, of van Single, Doubleof Decimal naar een integraal type, is het resultaat afhankelijk van of de controle van gehele getallen overflow is ingeschakeld:

    Als een overloop van gehele getallen wordt gecontroleerd:

    • Als de bron een integraal type is, slaagt de conversie als het bronargument binnen het bereik van het doeltype valt. De conversie genereert een System.OverflowException uitzondering als het bronargument buiten het bereik van het doeltype valt.

    • Als de bron Singlede bronwaarde is, Doubleof Decimal, wordt de bronwaarde naar boven of omlaag afgerond op de dichtstbijzijnde integrale waarde en wordt deze integrale waarde het resultaat van de conversie. Als de bronwaarde even dicht bij twee integrale waarden ligt, wordt de waarde afgerond op de waarde met een even getal in de minst significante cijferpositie. Als de resulterende integrale waarde buiten het bereik van het doeltype valt, wordt er een System.OverflowException uitzondering gegenereerd.

    Als overloop van gehele getallen niet wordt gecontroleerd:

    • Als de bron een integraal type is, slaagt de conversie altijd en bestaat alleen uit het verwijderen van de belangrijkste bits van de bronwaarde.

    • Als de bron Single, Doubleof Decimal, de conversie altijd slaagt en eenvoudigweg bestaat uit het afronden van de bronwaarde naar de dichtstbijzijnde integrale waarde. Als de bronwaarde even dicht bij twee integrale waarden ligt, wordt de waarde altijd afgerond op de waarde met een even getal in de minst significante cijferpositie.

  • Voor een conversie van Double naar Single, wordt de Double waarde afgerond op de dichtstbijzijnde Single waarde. Als de Double waarde te klein is om als een Singleweer te geven, wordt het resultaat positief nul of negatief nul. Als de Double waarde te groot is om als een Singleweer te geven, wordt het resultaat positief oneindig of negatief oneindig. Als de Double waarde is NaN, is het resultaat ook NaN.

  • Voor een conversie van Single of Double naar Decimal, wordt de bronwaarde indien nodig geconverteerd naar Decimal weergave en afgerond op het dichtstbijzijnde getal na de 28e decimale plaats. Als de bronwaarde te klein is om als een Decimalweer te geven, wordt het resultaat nul. Als de bronwaarde NaN, oneindigheid of te groot is om te vertegenwoordigen als een Decimal, wordt er een System.OverflowException uitzondering gegenereerd.

  • Voor een conversie van Double naar Single, wordt de Double waarde afgerond op de dichtstbijzijnde Single waarde. Als de Double waarde te klein is om als een Singleweer te geven, wordt het resultaat positief nul of negatief nul. Als de Double waarde te groot is om als een Singleweer te geven, wordt het resultaat positief oneindig of negatief oneindig. Als de Double waarde is NaN, is het resultaat ook NaN.

Verwijzingsconversies

Verwijzingstypen kunnen worden geconverteerd naar een basistype en omgekeerd. Conversies van een basistype naar een meer afgeleid type slagen alleen tijdens runtime als de waarde die wordt geconverteerd een null-waarde, het afgeleide type zelf of een meer afgeleid type is.

Klasse- en interfacetypen kunnen van en naar elk interfacetype worden gecast. Conversies tussen een type en een interfacetype slagen alleen tijdens runtime als de werkelijke typen een overname- of implementatierelatie hebben. Omdat een interfacetype altijd een exemplaar bevat van een type dat is afgeleid Objectvan, kan een interfacetype ook altijd worden gecast naar en van Object.

Opmerking. Het is geen fout om een NotInheritable klassen te converteren naar en van interfaces die niet worden geïmplementeerd omdat klassen die COM-klassen vertegenwoordigen mogelijk interface-implementaties hebben die pas bekend zijn als de runtime.

Als een verwijzingsconversie tijdens runtime mislukt, wordt er een System.InvalidCastException uitzondering gegenereerd.

Verwijzingsvariantieconversies

Algemene interfaces of gemachtigden kunnen varianttypeparameters hebben die conversies tussen compatibele varianten van het type toestaan. Daarom slaagt tijdens runtime een conversie van een klassetype of een interfacetype naar een interfacetype dat compatibel is met een interfacetype dat het overneemt van of implementeert. Op dezelfde manier kunnen gedelegeerdentypen worden gecast naar en van variant compatibele gedelegeerdentypen. Bijvoorbeeld het type gemachtigde

Delegate Function F(Of In A, Out R)(a As A) As R

zou een conversie van F(Of Object, Integer) naar F(Of String, Integer). Dat wil zeggen dat een gemachtigde F die Object veilig kan worden gebruikt als gemachtigde F die neemt String. Wanneer de gemachtigde wordt aangeroepen, verwacht de doelmethode een object en is een tekenreeks een object.

Een algemeen gemachtigde of interfacetype S(Of S1,...,Sn) wordt geacht variant te zijn die compatibel is met een algemene interface of gedelegeerdentype T(Of T1,...,Tn) als:

  • S en T beide zijn samengesteld op basis van hetzelfde algemene type U(Of U1,...,Un).

  • Voor elke typeparameter Ux:

    • Als de typeparameter zonder variantie Sx is gedeclareerd, Tx moet deze hetzelfde type zijn.

    • Als de typeparameter is gedeclareerd In , moet er een brede identiteit, standaardwaarde, verwijzing, matrix of typeparameterconversie van Sx naar Tx.

    • Als de typeparameter is gedeclareerd Out , moet er een brede identiteit, standaardwaarde, verwijzing, matrix of typeparameterconversie van Tx naar Sx.

Bij het converteren van een klasse naar een algemene interface met parameters van het varianttype, als de klasse meer dan één variant compatibele interface implementeert, is de conversie dubbelzinnig als er geen niet-variantconversie is. Voorbeeld:

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

Anonieme conversies van gemachtigden

Wanneer een expressie die is geclassificeerd als een lambda-methode opnieuw wordt geclassificeerd als een waarde in een context waarin er geen doeltype is (bijvoorbeeld Dim x = Function(a As Integer, b As Integer) a + b), of waarbij het doeltype geen gemachtigde is, is het type van de resulterende expressie een anoniem gemachtigdetype dat gelijk is aan de handtekening van de lambda-methode. Dit anonieme gemachtigdentype heeft een conversie naar elk compatibel gemachtigdetype: een compatibel gemachtigdetype is elk gemachtigdentype dat kan worden gemaakt met behulp van een expressie voor het maken van gedelegeerden met de methode van Invoke het anonieme gemachtigdetype als parameter. Voorbeeld:

' 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

Houd er rekening mee dat de typen System.Delegate en System.MulticastDelegate niet zelf worden beschouwd als gedelegeerdentypen (ook al nemen alle gedelegeerdentypen hiervan over). Houd er ook rekening mee dat de conversie van het anonieme gemachtigdetype naar een compatibel gemachtigdentype geen verwijzingsconversie is.

Matrixconversies

Naast de conversies die zijn gedefinieerd op matrices door het feit dat ze verwijzingstypen zijn, bestaan er verschillende speciale conversies voor matrices.

Voor twee typen A en B, als ze beide verwijzingstypen of typeparameters zijn die niet bekend zijn als waardetypen, en als A er een verwijzing, matrix of typeparameterconversie naar Bis, bestaat er een conversie van een matrix van het type A naar een matrix van het type B met dezelfde rang. Deze relatie staat bekend als matrixcovariantie. De covariantie van de matrix betekent met name dat een element van een matrix waarvan het elementtype daadwerkelijk een element kan B zijn waarvan het elementtype is A, mits A zowel B verwijzingstypen als verwijzingstypen zijn en die B een verwijzingsconversie of matrixconversie hebben naar A. In het volgende voorbeeld wordt door de tweede aanroep van F een uitzondering een System.ArrayTypeMismatchException uitzondering gegenereerd omdat het werkelijke elementtype b is String, niet 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

Vanwege de covariantie van de matrix bevatten toewijzingen aan elementen van referentietypematrices een runtimecontrole die ervoor zorgt dat de waarde die aan het matrixelement wordt toegewezen, daadwerkelijk van een toegestaan type is.

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

In dit voorbeeld bevat de toewijzing aan array(i) in de methode Fill impliciet een runtimecontrole die ervoor zorgt dat het object waarnaar wordt verwezen door de variabele value een Nothing exemplaar is van een type dat compatibel is met het werkelijke elementtype van de matrix array. In de methode Mainslagen de eerste twee aanroepen van de methode Fill , maar de derde aanroep zorgt ervoor dat er een System.ArrayTypeMismatchException uitzondering wordt gegenereerd bij het uitvoeren van de eerste opdracht aan array(i). De uitzondering treedt op omdat een IntegerString matrix niet kan worden opgeslagen.

Als een van de matrixelementtypen een typeparameter is waarvan het type tijdens runtime een waardetype blijkt te zijn, wordt er een System.InvalidCastException uitzondering gegenereerd. Voorbeeld:

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

Er bestaan ook conversies tussen een matrix van een geïnventariseerd type en een matrix van het onderliggende type van het enumerated type of een matrix van een ander geïnventariseerd type met hetzelfde onderliggende type, mits de matrices dezelfde rang hebben.

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

In dit voorbeeld wordt een matrix Color geconverteerd naar en van een matrix van ByteColorhet onderliggende type. De conversie naar een matrix van Integer, maar zal een fout zijn omdat Integer dit niet het onderliggende type Coloris.

Een matrix met rang-1 van het type A() heeft ook een matrixconversie naar de verzamelingsinterfacetypen IList(Of B), IReadOnlyCollection(Of B)IReadOnlyList(Of B)ICollection(Of B)en IEnumerable(Of B) gevonden in System.Collections.Generic, zolang een van de volgende waar is:

  • A en B zijn zowel verwijzingstypen als typeparameters die niet bekend zijn als waardetypen; en A hebben een brede verwijzing, matrix- of typeparameterconversie naar B; of
  • A en B zijn beide geïnventariseerd typen van hetzelfde onderliggende type; of
  • een van A en B is een geïnventariseerd type en het andere is het onderliggende type.

Elke matrix van het type A met een willekeurige rangschikking heeft ook een matrixconversie naar de niet-algemene verzamelingsinterfacetypen IList, ICollection en IEnumerable gevonden in System.Collections.

Het is mogelijk om de resulterende interfaces te herhalen met behulp van For Each, of door de GetEnumerator methoden rechtstreeks aan te roepen. In het geval van rank-1-matrices geconverteerde algemene of niet-generieke vormen van IList of ICollection, is het ook mogelijk om elementen op index te verkrijgen. In het geval van rank-1-matrices die zijn geconverteerd naar algemene of niet-generieke vormen, is het ook mogelijk om elementen in te stellen op basis van IListindex, afhankelijk van dezelfde covariantiecontroles van runtimematrix zoals hierboven beschreven. Het gedrag van alle andere interfacemethoden is niet gedefinieerd door de VB-taalspecificatie; het is aan de onderliggende runtime.

Conversies van waardetype

Een waardetypewaarde kan worden geconverteerd naar een van de basisverwijzingstypen of een interfacetype dat wordt geïmplementeerd via een proces dat boksen wordt genoemd. Wanneer een waardetypewaarde in een vak wordt geplaatst, wordt de waarde gekopieerd van de locatie waar deze zich op de .NET Framework-heap bevindt. Een verwijzing naar deze locatie op de heap wordt vervolgens geretourneerd en kan worden opgeslagen in een referentietypevariabele. Deze verwijzing wordt ook wel een boxed exemplaar van het waardetype genoemd. Het vakexemplaren hebben dezelfde semantiek als een verwijzingstype in plaats van een waardetype.

In een vak geplaatste waardetypen kunnen opnieuw worden geconverteerd naar het oorspronkelijke waardetype via een proces met de naam Unboxing. Wanneer een waardetype in een vak is uitgeschakeld, wordt de waarde uit de heap gekopieerd naar een variabele locatie. Vanaf dat moment gedraagt het zich alsof het een waardetype was. Bij het uitpakken van een waardetype moet de waarde een null-waarde of een exemplaar van het waardetype zijn. Anders wordt er een System.InvalidCastException uitzondering gegenereerd. Als de waarde een instantie is van een geïnventariseerd type, kan die waarde ook worden uitgeschreven naar het onderliggende type van het enumerated type of een ander geïnventariseerd type dat hetzelfde onderliggende type heeft. Een null-waarde wordt behandeld alsof deze de letterlijke waarde Nothingis.

Ter ondersteuning van typen null-waarden wordt het waardetype System.Nullable(Of T) speciaal behandeld bij boksen en uitpakken. Als u een waarde van het type Nullable(Of T) in een vakwaarde van het type T opgeeft, of de eigenschap van HasValue de waarde een waarde is True of een waarde van Nothing als de eigenschap van HasValue de waarde is False. Als u een waarde van het type T opheffen, Nullable(Of T) wordt het resultaat weergegeven in een instantie van Nullable(Of T) wie Value de eigenschap de waarde in het vak is en waarvan HasValue de eigenschap is True. De waarde kan worden uitgepakt Nullable(Of T) voor elke T waarde Nothing en resulteert in een waarde waarvan HasValue de eigenschap isFalse. Omdat waardetypen in vakken zich gedragen als verwijzingstypen, is het mogelijk om meerdere verwijzingen naar dezelfde waarde te maken. Voor de primitieve typen en opgesomde typen is dit niet relevant omdat instanties van deze typen onveranderbaar zijn. Dat wil gezegd, het is niet mogelijk om een boxed exemplaar van deze typen te wijzigen, dus het is niet mogelijk om te observeren dat er meerdere verwijzingen naar dezelfde waarde zijn.

Structuren kunnen daarentegen veranderlijk zijn als de exemplaarvariabelen toegankelijk zijn of als de methoden of eigenschappen ervan de exemplaarvariabelen wijzigen. Als één verwijzing naar een vakkenstructuur wordt gebruikt om de structuur te wijzigen, zien alle verwijzingen naar de vakkenstructuur de wijziging. Omdat dit resultaat onverwacht kan zijn, wordt een waarde die is getypt Object van de ene locatie naar een andere vakkenwaarde automatisch gekloond op de heap in plaats van alleen de verwijzingen te laten kopiëren. Voorbeeld:

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

De uitvoer van het programma is:

Values: 0, 123
Refs: 123, 123

De toewijzing aan het veld van de lokale variabele val2 heeft geen invloed op het veld van de lokale variabele val1 , omdat er een kopie van de waarde is gemaakt wanneer het vak Struct1 is toegewezen val2aan. De toewijzing ref2.Value = 123 is daarentegen van invloed op het object dat zowel ref1 als ref2 verwijzingen bevat.

Opmerking. Het kopiëren van structuur wordt niet uitgevoerd voor geboksde structuren die zijn getypt System.ValueType omdat het niet mogelijk is om te laat binden van System.ValueType.

Er is één uitzondering op de regel waarvoor waardetypen in vakken worden gekopieerd bij de toewijzing. Als een verwijzing naar een waardetype in een vak wordt opgeslagen binnen een ander type, wordt de interne verwijzing niet gekopieerd. Voorbeeld:

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

De uitvoer van het programma is:

Values: 123, 123

Dit komt doordat de waarde in het binnenste vak niet wordt gekopieerd wanneer de waarde wordt gekopieerd. val1.Value Beide hebben val2.Value dus een verwijzing naar hetzelfde waardetype in een vak.

Opmerking. Het feit dat binnenste waardetypen niet worden gekopieerd, is een beperking van het .NET-typesysteem, om ervoor te zorgen dat alle binnenste waardetypen worden gekopieerd wanneer een waarde van het type Object werd gekopieerd, te duur zou zijn.

Zoals eerder beschreven, kunnen waardetypen in vakken alleen worden uitgeschreven naar het oorspronkelijke type. Boksen primitieve typen worden echter speciaal behandeld wanneer getypt als Object. Ze kunnen worden geconverteerd naar elk ander primitief type waarnaar ze een conversie hebben. Voorbeeld:

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

Normaal gesproken kan de waarde 5 in vakken Integer niet worden ingepakt in een Byte variabele. Omdat Integer en Byte primitieve typen zijn en een conversie hebben, is de conversie echter toegestaan.

Het is belangrijk te weten dat het converteren van een waardetype naar een interface anders is dan een algemeen argument dat is beperkt tot een interface. Wanneer u interfaceleden opent voor een parameter met een beperkt type (of methoden Objectaanroept), gebeurt boksen niet zoals het geval is wanneer een waardetype wordt geconverteerd naar een interface en een interfacelid wordt geopend. Stel dat een interface ICounter een methode Increment bevat die kan worden gebruikt om een waarde te wijzigen. Als ICounter deze wordt gebruikt als een beperking, wordt de implementatie van de Increment methode aangeroepen met een verwijzing naar de variabele die Increment is aangeroepen, niet een boxed kopie:

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

De eerste aanroep van Increment wijzigt de waarde in de variabele x. Dit is niet gelijk aan de tweede aanroep van Increment, die de waarde wijzigt in een vakkenkopie van x. De uitvoer van het programma is dus:

0
1
1

Conversies van type null-waarde

Een waardetype T kan worden geconverteerd naar en van de null-versie van het type, T?. De conversie van T? naar genereert T een System.InvalidOperationException uitzondering als de waarde die wordt geconverteerd is Nothing. T? Heeft ook een conversie naar een type S als T een intrinsieke conversie naar S. En als S een waardetype is, bestaan de volgende intrinsieke conversies tussen T? en S?:

  • Een conversie van dezelfde classificatie (narrowing of widening) van T? naar S?.

  • Een conversie van dezelfde classificatie (narrowing of widening) van T naar S?.

  • Een vermalingsconversie van S? naar T.

Een intrinsieke widening conversie bestaat bijvoorbeeld van Integer? naar Long? omdat er een intrinsieke widening conversie bestaat van Integer naar Long:

Dim i As Integer? = 10
Dim l As Long? = i

Bij het converteren van T? naar S?, als de waarde T? is Nothing, is de waarde van S? .Nothing Bij het converteren van S? of TT? naar S, als de waarde van T? of S? is Nothing, wordt er een System.InvalidCastException uitzondering gegenereerd.

Vanwege het gedrag van het onderliggende type System.Nullable(Of T), wanneer een type null-waarde T? in een vak wordt geplaatst, is het resultaat een vakkenwaarde van het type T, niet een waarde in een vak van het type T?. En, omgekeerd, bij het uitpakken van een null-waardetype T?, wordt de waarde verpakt door System.Nullable(Of T)en Nothing wordt deze uitgezet naar een null-waarde van het type T?. Voorbeeld:

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

Een neveneffect van dit gedrag is dat een type null-waarde T? lijkt te implementeren alle interfaces van T, omdat het converteren van een waardetype naar een interface vereist dat het type in een vak wordt geplaatst. Als gevolg hiervan T? is converteerbaar naar alle interfaces die T converteerbaar zijn naar. Het is echter belangrijk te weten dat een type nullable waarde T? niet daadwerkelijk de interfaces T implementeert voor algemene beperkingscontrole of weerspiegeling. Voorbeeld:

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

Tekenreeksconversies

Char Converteren naar String resultaten in een tekenreeks waarvan het eerste teken de tekenwaarde is. String Converteren naar Char resultaten in een teken waarvan de waarde het eerste teken van de tekenreeks is. Als u een matrix Char converteert naar String resultaten in een tekenreeks waarvan de tekens de elementen van de matrix zijn. String Converteren naar een matrix met Char resultaten in een matrix met tekens waarvan de elementen de tekens van de tekenreeks zijn.

De exacte conversies tussen String enBoolean, ByteUShortShortSByteUInteger, Integer, ULongDecimalSingleLongDouble, en Datevice versa, vallen buiten het bereik van deze specificatie en zijn afhankelijk van de implementatie met uitzondering van één detail. Tekenreeksconversies houden altijd rekening met de huidige cultuur van de runtime-omgeving. Daarom moeten ze tijdens runtime worden uitgevoerd.

Conversies breder maken

Het breder maken van conversies loopt nooit over, maar kan leiden tot verlies van precisie. De volgende conversies zijn het breder maken van conversies:

Identiteit/standaardconversies

  • Van een type tot zichzelf.

  • Van een anoniem gemachtigdetype dat is gegenereerd voor een herclassificatie van een lambda-methode naar elk gemachtigdentype met een identieke handtekening.

  • Van de letterlijke Nothing naar een type.

Numerieke conversies

  • Van Byte naar UShort, Short, , UInteger, Integer, , ULong, Long, , Decimal, , Singleof Double.

  • Van SByte tot Short, Integer, Long, Decimal, Single, of Double.

  • Van UShort tot UInteger, Integer, ULong, Long, Decimal, Singleof Double.

  • Van Short naar Integer, Long, of SingleDecimalDouble.

  • Van UInteger tot ULong, Long, Decimal, Singleof Double.

  • Van Integer naar Long, Decimalof SingleDouble.

  • Van ULong tot Decimal, Single, of Double.

  • Van Long naar Decimal, Single of Double.

  • Van Decimal tot Single of Double.

  • Van Single tot Double.

  • Van de letterlijke 0 naar een geïnventariseerd type. (Opmerking. De conversie van 0 elk geïnventariseerd type wordt breder om testvlagmen te vereenvoudigen. Als dit bijvoorbeeld Values een geïnventariseerd type met een waarde Oneis, kunt u een variabele v van het type Values testen door (v And Values.One) = 0te zeggen .)

  • Van een geïnventariseerd type naar het onderliggende numerieke type, of naar een numeriek type waarnaar het onderliggende numerieke type een verbreidingsconversie heeft.

  • Van een constante expressie van het type ULong, , Long, IntegerUInteger, UShort, Shortof ByteSByte tot een smaller type , mits de waarde van de constante expressie binnen het bereik van het doeltype valt. (Opmerking. Conversies van UInteger of Integer naar Single, ULong of Long naar Single of Double, of DecimalSingleDouble kunnen leiden tot een verlies van precisie, maar zullen nooit een verlies van grootte veroorzaken. De andere verbreidende numerieke conversies verliezen nooit informatie.)

Verwijzingsconversies

  • Van een verwijzingstype naar een basistype.

  • Van een verwijzingstype naar een interfacetype, mits het type de interface of een variant-compatibele interface implementeert.

  • Van een interfacetype naar Object.

  • Van een interfacetype tot een variant compatibel interfacetype.

  • Van een type gemachtigde tot een variant die compatibel is met de gemachtigde. (Opmerking. Veel andere verwijzingsconversies worden geïmpliceerd door deze regels. Anonieme gemachtigden zijn bijvoorbeeld verwijzingstypen die overnemen van System.MulticastDelegate; matrixtypen zijn verwijzingstypen die overnemen van System.Array; anonieme typen zijn verwijzingstypen die overnemen van System.Object.)

Anonieme conversies van gemachtigden

  • Van een anoniem gemachtigdentype dat is gegenereerd voor een herclassificatie van de lambda-methode naar een breder type gemachtigde.

Matrixconversies

  • Van een matrixtype met een elementtype SSe tot een matrixtype T met een elementtype Te, mits alle volgende waar zijn:

    • S en T verschilt alleen in elementtype.

    • Beide Se en Te zijn verwijzingstypen of zijn typeparameters die een verwijzingstype zijn.

    • Er bestaat een verbreidingsreferentie, matrix of typeparameterconversie van Se naar Te.

  • Van een matrixtype S met een geïnventariseerd elementtype Se tot een matrixtype T met een elementtype Te, mits alle volgende waar zijn:

    • S en T verschilt alleen in elementtype.

    • Te is het onderliggende type Se.

  • Van een matrixtype S van rang 1 met een geïnventariseerd elementtype Se, tot System.Collections.Generic.IList(Of Te), IReadOnlyList(Of Te)ICollection(Of Te), , IReadOnlyCollection(Of Te)en , mits IEnumerable(Of Te)een van de volgende is waar:

    • Beide Se en Te zijn verwijzingstypen of zijn typeparameters die een verwijzingstype zijn en een widening verwijzing, matrix of typeparameterconversie bestaat van Se naar Te; of

    • Te is het onderliggende type ; Seof

    • Te is identiek aan Se

Conversies van waardetype

  • Van een waardetype naar een basistype.

  • Van een waardetype tot een interfacetype dat door het type wordt geïmplementeerd.

Conversies van null-waardetype

  • Van een type T tot het type T?.

  • Van een type T? naar een type S?, waarbij er een verbreedingsconversie is van het type T naar het type S.

  • Van een type T naar een type S?, waarbij er een verbreedingsconversie is van het type T naar het type S.

  • Van een type T? naar een interfacetype dat door het type T wordt geïmplementeerd.

Tekenreeksconversies

  • Van Char tot String.

  • Van Char() tot String.

Type parameterconversies

  • Van een typeparameter naar Object.

  • Van een typeparameter tot een interfacetypebeperking of een interfacevariant die compatibel is met een interfacetypebeperking.

  • Van een typeparameter naar een interface die wordt geïmplementeerd door een klassebeperking.

  • Van een typeparameter tot een interfacevariant die compatibel is met een interface die is geïmplementeerd door een klassebeperking.

  • Van een typeparameter tot een klassebeperking of een basistype van de klassebeperking.

  • Van een typeparameter T tot een typeparameterbeperking Tx, of iets anders Tx heeft een brede conversie naar.

Conversies beperken

Vermalingsconversies zijn conversies die niet altijd kunnen worden bewezen, conversies waarvan bekend is dat ze mogelijk informatie verliezen en conversies tussen domeinen van typen voldoende verschillend zijn om de vermalings notatie te verdienen. De volgende conversies worden geclassificeerd als smalle conversies:

Booleaanse conversies

  • Van Boolean naar Byte, SByte, , UShort, Short, , UIntegerInteger, ULong, , Long, Decimal, , of SingleDouble.

  • Van Byte, SByte, UShort, Short, , UInteger, Integer, ULong, Long, , Decimal, , of SingleDouble naar Boolean.

Numerieke conversies

  • Van Byte tot SByte.

  • Van SByte tot Byte, UShort, UIntegerof ULong.

  • Van UShort tot Byte, SByte, of Short.

  • Van Short tot Byte, SByte, UShort, UIntegerof ULong.

  • Van UInteger tot Byte, SByte, UShort, Shortof Integer.

  • Van Integer tot Byte, SByte, UShort, Short, UInteger, of ULong.

  • Van ULong tot Byte, SByte, UShort, Short, UInteger, Integerof Long.

  • Van Long tot Byte, SByte, UShort, Short, UInteger, Integerof ULong.

  • Van Decimal naar Byte, SByte, UShort, Short, UInteger, Integer, ULongof Long.

  • Van Single naar Byte, SByte, , UShort, Short, , UInteger, Integer, , ULong, , Longof Decimal.

  • Van Double naar Byte, SByte, , UShort, Short, , UInteger, Integer, , ULong, Long, , , , Decimalof Single.

  • Van een numeriek type naar een geïnventariseerd type.

  • Van een geïnventariseerd type naar een numeriek type waar het onderliggende numerieke type een smalle conversie naar heeft.

  • Van een geïnventariseerd type naar een ander geïnventariseerd type.

Verwijzingsconversies

  • Van een verwijzingstype naar een meer afgeleid type.

  • Van een klassetype tot een interfacetype, mits het klassetype het interfacetype niet implementeert of een interfacetypevariant die ermee compatibel is.

  • Van een interfacetype naar een klassetype.

  • Van een interfacetype naar een ander interfacetype, mits er geen overnamerelatie is tussen de twee typen en mits ze niet compatibel zijn met varianten.

Anonieme conversies van gemachtigden

  • Van een anoniem gemachtigdentype dat is gegenereerd voor een herclassificatie van een lambda-methode naar elk smaller gemachtigdetype.

Matrixconversies

  • Van een matrixtype met een elementtype SSetot een matrixtype met een elementtype TTe, mits alle volgende waar zijn:

    • S en T verschilt alleen in elementtype.
    • Beide Se en Te zijn verwijzingstypen of zijn typeparameters die geen waardetypen zijn.
    • Er bestaat een vermalingsverwijzing, matrix of typeparameterconversie van Se naar Te.
  • Van een matrixtype met een elementtype SSe tot een matrixtype T met een geïnventariseerd elementtype Te, mits alle volgende waar zijn:

    • S en T verschilt alleen in elementtype.
    • Se is het onderliggende type Te , of ze zijn beide verschillende geïnventariseerd typen die hetzelfde onderliggende type delen.
  • Van een matrixtype S van rang 1 met een geïnventariseerd elementtype Se, tot IList(Of Te)IReadOnlyList(Of Te), ICollection(Of Te)en IReadOnlyCollection(Of Te) , mits IEnumerable(Of Te)een van de volgende is waar:

    • Beide Se en Te zijn verwijzingstypen of zijn typeparameters die een verwijzingstype zijn, en een vermalende verwijzing, matrix of typeparameterconversie bestaat van Se tot Te; of
    • Se is het onderliggende type Te, of ze zijn beide verschillende geïnventariseerd typen die hetzelfde onderliggende type delen.

Conversies van waardetypen

  • Van een verwijzingstype naar een meer afgeleid waardetype.

  • Van een interfacetype tot een waardetype, mits het waardetype het interfacetype implementeert.

Conversies van null-waardetype

  • Van een type T? naar een type T.

  • Van een type T? naar een type S?, waarbij er een smalle conversie is van het type T naar het type S.

  • Van een type T naar een type S?, waarbij er een smalle conversie is van het type T naar het type S.

  • Van een type S? naar een type T, waarbij er een conversie is van het type S naar het type T.

Tekenreeksconversies

  • Van String tot Char.

  • Van String tot Char().

  • Van String en Boolean naar BooleanString.

  • Conversies tussen String en Byte, SByte, , UShort, Short, , UInteger, Integer, , ULongLong, , Decimal, of SingleDouble.

  • Van String en Date naar DateString.

Type parameterconversies

  • Van Object naar een typeparameter.

  • Van een typeparameter tot een interfacetype, mits de typeparameter niet is beperkt tot die interface of beperkt is tot een klasse die die interface implementeert.

  • Van een interfacetype naar een typeparameter.

  • Van een typeparameter tot een afgeleid type van een klassebeperking.

  • Van een typeparameter T tot alles waar een typeparameterbeperking Tx een narrowing conversie naar heeft.

Type parameterconversies

De conversies van typeparameters worden bepaald door de beperkingen, indien van toepassing, op deze parameters. Een typeparameter T kan altijd naar zichzelf worden geconverteerd, van en Objectnaar en van elk interfacetype. Houd er rekening mee dat als het type T een waardetype is tijdens de runtime, het converteren van T naar Object of een interfacetype een boksconversie is en converteren van Object of een interfacetype waarnaar T wordt geconverteerd, een conversie van het postvak UIT is. Een typeparameter met een klassebeperking C definieert extra conversies van de typeparameter naar C de basisklassen en omgekeerd. Een typeparameter T met een typeparameterbeperking Tx definieert een conversie naar Tx en alles Tx wordt geconverteerd naar.

Een matrix waarvan het elementtype een typeparameter is met een interfacebeperking I , heeft dezelfde covariantmatrixconversies als een matrix waarvan het elementtype is I, mits de typeparameter ook een Class of klassebeperking heeft (omdat alleen verwijzingstype matrixelementtypen covariant kunnen zijn). Een matrix waarvan het elementtype een typeparameter is met een klassebeperking C , heeft dezelfde covariantmatrixconversies als een matrix waarvan het elementtype is C.

De bovenstaande conversieregels staan conversies van niet-getrainde typeparameters niet toe naar niet-interfacetypen, wat verrassend kan zijn. De reden hiervoor is om verwarring te voorkomen over de semantiek van dergelijke conversies. Denk bijvoorbeeld aan de volgende declaratie:

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

Als de conversie van T het ton Integer is toegestaan, kan men gemakkelijk verwachten dat dat X(Of Integer).F(7) zou retourneren 7L. Dit zou echter niet gebeuren, omdat numerieke conversies alleen worden overwogen wanneer de typen numeriek zijn tijdens het compileren. Om de semantiek duidelijk te maken, moet het bovenstaande voorbeeld in plaats daarvan worden geschreven:

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 conversies

Intrinsieke conversies zijn conversies die zijn gedefinieerd door de taal (bijvoorbeeld vermeld in deze specificatie), terwijl door de gebruiker gedefinieerde conversies worden gedefinieerd door een overbelasting van de CType operator. Als er geen intrinsieke conversies van toepassing zijn tussen typen, worden door de gebruiker gedefinieerde conversies overwogen. Als er een door de gebruiker gedefinieerde conversie is die het meest specifiek is voor de bron- en doeltypen, wordt de door de gebruiker gedefinieerde conversie gebruikt. Anders treedt er een fout op basis van een compilatietijd op. De meest specifieke conversie is degene waarvan de operand het dichtst bij het brontype ligt en waarvan het resultaattype het dichtst bij het doeltype ligt. Bij het bepalen welke door de gebruiker gedefinieerde conversie moet worden gebruikt, wordt de meest specifieke widening-conversie gebruikt; als er geen widening conversie het meest specifiek is, wordt de meest specifieke narrowing conversie gebruikt. Als er geen specifieke vermalingsconversie is, is de conversie niet gedefinieerd en treedt er een compilatiefout op.

In de volgende secties wordt beschreven hoe de meest specifieke conversies worden bepaald. Ze gebruiken de volgende termen:

Als er een intrinsiek verbreidingsconversie bestaat van een type A naar een type B, en als dit geen AB van beide interfaces zijn, A wordt dit omvat door Ben BomvatA het.

Het meest omvattende type in een set typen is het ene type dat alle andere typen in de set omvat. Als geen enkel type alle andere typen omvat, heeft de set geen omvattend type. In intuïtieve termen is het meest omvattende type het 'grootste' type in de set- het ene type waarnaar elk van de andere typen kan worden geconverteerd via een widening-conversie.

Het meest omvattende type in een set typen is het ene type dat wordt omvat door alle andere typen in de set. Als er geen enkel type is opgenomen in alle andere typen, heeft de set geen meest omvattend type. In intuïtieve termen is het meest omvattende type het 'kleinste' type in de set, het ene type dat kan worden geconverteerd naar elk van de andere typen via een smalle conversie.

Bij het verzamelen van de door de gebruiker gedefinieerde kandidaatconversies voor een type T?worden in plaats daarvan de door de gebruiker gedefinieerde T conversieoperators gebruikt. Als het type waarnaar wordt geconverteerd ook een type null-waarde is, worden Talle door de gebruiker gedefinieerde conversieoperators die alleen niet-null-waardetypen omvatten, opgeheven. Een conversieoperator van T naar wordt S opgeheven als een conversie van T? naar S? en wordt geëvalueerd doorTT?, indien nodig, de door de gebruiker gedefinieerde conversieoperator T te evalueren van naar S en vervolgens te converteren S naar S?, indien nodig. Als de waarde die wordt geconverteerd Nothing, echter een lifted conversieoperator rechtstreeks wordt omgezet in een waarde van Nothing getypt als S?. Voorbeeld:

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

Bij het omzetten van conversies hebben door de gebruiker gedefinieerde conversieoperators altijd de voorkeur boven lifted conversieoperators. Voorbeeld:

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

Tijdens runtime kan het evalueren van een door de gebruiker gedefinieerde conversie maximaal drie stappen omvatten:

  1. Eerst wordt de waarde van het brontype geconverteerd naar het operandtype met behulp van een intrinsieke conversie, indien nodig.

  2. Vervolgens wordt de door de gebruiker gedefinieerde conversie aangeroepen.

  3. Ten slotte wordt het resultaat van de door de gebruiker gedefinieerde conversie geconverteerd naar het doeltype met behulp van een intrinsieke conversie, indien nodig.

Het is belangrijk te weten dat de evaluatie van een door de gebruiker gedefinieerde conversie nooit meer dan één door de gebruiker gedefinieerde conversieoperator omvat.

Meest specifieke verbreedingsconversie

Het bepalen van de meest specifieke door de gebruiker gedefinieerde conversieoperator tussen twee typen wordt bereikt met behulp van de volgende stappen:

  1. Eerst worden alle kandidaatconversieoperators verzameld. De operators voor kandidaatconversie zijn alle door de gebruiker gedefinieerde widening-conversieoperators in het brontype en alle door de gebruiker gedefinieerde operatoren voor widening-conversie in het doeltype.

  2. Vervolgens worden alle niet-toepasselijke conversieoperators uit de set verwijderd. Een conversieoperator is van toepassing op een brontype en doeltype als er een intrinsiek verbreidingsconversieoperator van het brontype naar het operandtype is en er een intrinsieke widening conversieoperator is van het resultaat van de operator naar het doeltype. Als er geen toepasselijke conversieoperators zijn, is er geen specifieke verbreedingsconversie.

  3. Vervolgens wordt het meest specifieke brontype van de toepasselijke conversieoperators bepaald:

    • Als een van de conversieoperators rechtstreeks van het brontype wordt geconverteerd, is het brontype het meest specifieke brontype.

    • Anders is het meest specifieke brontype het meest omvattende type in de gecombineerde set brontypen van de conversieoperators. Als er geen meest omvattend type kan worden gevonden, is er geen specifieke widening conversie.

  4. Vervolgens wordt het meest specifieke doeltype van de toepasselijke conversieoperators bepaald:

    • Als een van de conversieoperators rechtstreeks naar het doeltype wordt geconverteerd, is het doeltype het meest specifieke doeltype.

    • Anders is het meest specifieke doeltype het meest omvattende type in de gecombineerde set doeltypen van de conversieoperators. Als er geen meest omvattend type kan worden gevonden, is er geen specifieke widening conversie.

  5. Als er vervolgens precies één conversieoperator wordt geconverteerd van het meest specifieke brontype naar het meest specifieke doeltype, is dit de meest specifieke conversieoperator. Als er meer dan één dergelijke operator bestaat, is er geen specifieke verbreedingsconversie.

Meest specifieke vermalingsconversie

Het bepalen van de meest specifieke door de gebruiker gedefinieerde narrowing conversieoperator tussen twee typen wordt bereikt met behulp van de volgende stappen:

  1. Eerst worden alle kandidaatconversieoperators verzameld. De operators voor kandidaatconversie zijn alle door de gebruiker gedefinieerde conversieoperators in het brontype en alle door de gebruiker gedefinieerde conversieoperators in het doeltype.

  2. Vervolgens worden alle niet-toepasselijke conversieoperators uit de set verwijderd. Een conversieoperator is van toepassing op een brontype en doeltype als er een intrinsieke conversieoperator van het brontype naar het operandtype is en er een intrinsieke conversieoperator is van het resultaat van de operator naar het doeltype. Als er geen toepasselijke conversieoperators zijn, is er geen specifieke narrowing-conversie.

  3. Vervolgens wordt het meest specifieke brontype van de toepasselijke conversieoperators bepaald:

    • Als een van de conversieoperators rechtstreeks van het brontype wordt geconverteerd, is het brontype het meest specifieke brontype.

    • Als een van de conversieoperators wordt geconverteerd van typen die het brontype omvatten, is het meest specifieke brontype het meest omvattende type in de gecombineerde set brontypen van deze conversieoperators. Als er geen meest omvattend type kan worden gevonden, is er geen specifieke vermalingsconversie.

    • Anders is het meest specifieke brontype het meest omvattende type in de gecombineerde set brontypen van de conversieoperators. Als er geen meest omvattend type kan worden gevonden, is er geen specifieke vermalingsconversie.

  4. Vervolgens wordt het meest specifieke doeltype van de toepasselijke conversieoperators bepaald:

    • Als een van de conversieoperators rechtstreeks naar het doeltype wordt geconverteerd, is het doeltype het meest specifieke doeltype.

    • Als een van de conversieoperators wordt geconverteerd naar typen die zijn opgenomen in het doeltype, is het meest specifieke doeltype het meest omvattende type in de gecombineerde set brontypen van deze conversieoperators. Als er geen meest omvattend type kan worden gevonden, is er geen specifieke vermalingsconversie.

    • Anders is het meest specifieke doeltype het meest omvattende type in de gecombineerde set doeltypen van de conversieoperators. Als er geen meest omvattend type kan worden gevonden, is er geen specifieke vermalingsconversie.

  5. Als er vervolgens precies één conversieoperator wordt geconverteerd van het meest specifieke brontype naar het meest specifieke doeltype, is dit de meest specifieke conversieoperator. Als er meer dan één dergelijke operator bestaat, is er geen specifieke vermalingsconversie.

Systeemeigen conversies

Verschillende van de conversies worden geclassificeerd als systeemeigen conversies , omdat ze systeemeigen worden ondersteund door .NET Framework. Deze conversies zijn conversies die kunnen worden geoptimaliseerd via het gebruik van de DirectCast operators en TryCast conversieoperatoren, evenals andere speciale gedragingen. De conversies die zijn geclassificeerd als systeemeigen conversies zijn: identiteitsconversies, standaardconversies, verwijzingsconversies, matrixconversies, conversies van waardetypen en typeparameterconversies.

Dominant Type

Gezien een reeks typen is het vaak noodzakelijk in situaties zoals typedeductie om het dominante type van de set te bepalen. Het dominante type van een set typen wordt bepaald door eerst alle typen te verwijderen waarnaar een of meer andere typen geen impliciete conversie hebben. Als er op dit moment geen typen meer zijn, is er geen dominant type. Het dominante type is dan het meest omvat van de resterende typen. Als er meer dan één type is dat het meest wordt omvat, is er geen dominant type.