Bagikan melalui


Konversi di Visual Basic

Konversi adalah proses mengubah nilai dari satu jenis ke jenis lainnya. Misalnya, nilai jenis Integer dapat dikonversi ke nilai jenis Double, atau nilai jenis Derived dapat dikonversi ke nilai jenis Base, dengan asumsi bahwa Base dan Derived merupakan kelas dan Derived warisan dari Base. Konversi mungkin tidak memerlukan nilai itu sendiri untuk berubah (seperti dalam contoh terakhir), atau mungkin memerlukan perubahan signifikan dalam representasi nilai (seperti dalam contoh sebelumnya).

Konversi mungkin melebar atau menyempit. Konversi yang melebar adalah konversi dari jenis ke jenis lain yang domain nilainya setidaknya sebesar, jika tidak lebih besar, daripada domain nilai jenis asli. Melebarkan konversi seharusnya tidak pernah gagal. Konversi yang dipersempit adalah konversi dari jenis ke jenis lain yang domain nilainya lebih kecil dari domain nilai jenis asli atau cukup tidak terkait bahwa perawatan tambahan harus diambil saat melakukan konversi (misalnya, saat mengonversi dari Integer ke String). Konversi yang mempersempit, yang mungkin memerlukan hilangnya informasi, dapat gagal.

Konversi identitas (yaitu konversi dari jenis ke dirinya sendiri) dan konversi nilai default (yaitu konversi dari Nothing) didefinisikan untuk semua jenis.

Konversi Implisit dan Eksplisit

Konversi dapat berupa implisit atau eksplisit. Konversi implisit terjadi tanpa sintaks khusus. Berikut ini adalah contoh konversi implisit nilai Integer ke Long nilai:

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

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

Konversi eksplisit, di sisi lain, memerlukan operator transmisi. Mencoba melakukan konversi eksplisit pada nilai tanpa operator cast menyebabkan kesalahan waktu kompilasi. Contoh berikut menggunakan konversi eksplisit untuk mengonversi nilai menjadi LongInteger nilai.

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

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

Kumpulan konversi implisit tergantung pada lingkungan kompilasi dan Option Strict pernyataan. Jika semantik ketat digunakan, hanya konversi yang melebar dapat terjadi secara implisit. Jika semantik permisif digunakan, semua konversi yang melebar dan mempersempit (dengan kata lain, semua konversi) dapat terjadi secara implisit.

Konversi Boolean

Meskipun Boolean bukan jenis numerik, itu memang memiliki konversi yang mempersempit ke dan dari jenis numerik seolah-olah itu adalah jenis enumerasi. Harfiah True mengonversi ke harfiah 255 untuk Byte, 65535 untuk UShort, 4294967295 untuk UInteger, 18446744073709551615 untuk ULong, dan ke ekspresi -1 untuk SByte, , Short, IntegerLong, Decimal, Single, dan Double. Harfiah False mengonversi ke literal 0. Nilai numerik nol dikonversi ke literal False. Semua nilai numerik lainnya dikonversi ke literal True.

Ada konversi yang mempersempit dari Boolean ke String, mengonversi ke atau System.Boolean.TrueStringSystem.Boolean.FalseString. Ada juga konversi yang mempersempit dari String ke Boolean: jika string sama dengan TrueString atau FalseString (dalam budaya saat ini, tidak peka huruf besar/kecil) maka ia menggunakan nilai yang sesuai; jika tidak, ia mencoba mengurai string sebagai jenis numerik (dalam hekses atau oktal jika memungkinkan, jika tidak, jika tidak sebagai float) dan menggunakan aturan di atas; jika tidak, ia melemparkan System.InvalidCastException.

Konversi Numerik

Konversi numerik ada di antara jenis Byte, , , UShortSByteShort, UInteger, Integer, ULong, , LongDecimal, , Single dan Double, dan semua jenis enumerasi. Saat dikonversi, jenis enumerasi diperlakukan seolah-olah mereka adalah jenis yang mendasarnya. Saat mengonversi ke jenis enumerasi, nilai sumber tidak diperlukan untuk menyesuaikan dengan kumpulan nilai yang ditentukan dalam jenis enumerasi. Contohnya:

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

Konversi numerik diproses pada run-time sebagai berikut:

  • Untuk konversi dari jenis numerik ke jenis numerik yang lebih luas, nilainya hanya dikonversi ke jenis yang lebih luas. Konversi dari UInteger, , IntegerULong, Long, atau Decimal ke Single atau Double dibulatkan ke nilai atau Double terdekatSingle. Meskipun konversi ini dapat menyebabkan hilangnya presisi, itu tidak akan pernah menyebabkan hilangnya besaran.

  • Untuk konversi dari jenis integral ke jenis integral lain, atau dari Single, Double, atau Decimal ke jenis integral, hasilnya tergantung pada apakah pemeriksaan luapan bilangan bulat aktif:

    Jika luapan bilangan bulat sedang diperiksa:

    • Jika sumber adalah jenis integral, konversi berhasil jika argumen sumber berada dalam rentang jenis tujuan. Konversi melemparkan System.OverflowException pengecualian jika argumen sumber berada di luar rentang jenis tujuan.

    • Jika sumbernya adalah Single, , Doubleatau Decimal, nilai sumber dibulatkan ke atas atau ke bawah ke nilai integral terdekat, dan nilai integral ini menjadi hasil konversi. Jika nilai sumber sama dekat dengan dua nilai integral, nilai dibulatkan ke nilai yang memiliki angka genap dalam posisi digit yang paling tidak signifikan. Jika nilai integral yang dihasilkan berada di luar rentang jenis tujuan, System.OverflowException pengecualian akan dilemparkan.

    Jika luapan bilangan bulat tidak diperiksa:

    • Jika sumber adalah jenis integral, konversi selalu berhasil dan hanya terdiri dari membuang bit yang paling signifikan dari nilai sumber.

    • Jika sumbernya adalah Single, , Doubleatau Decimal, konversi selalu berhasil dan hanya terdiri dari pembulatan nilai sumber menuju nilai integral terdekat. Jika nilai sumber sama dekat dengan dua nilai integral, nilai selalu dibulatkan ke nilai yang memiliki angka genap dalam posisi digit yang paling tidak signifikan.

  • Untuk konversi dari Double ke Single, nilai dibulatkan Double ke nilai terdekat Single . Double Jika nilai terlalu kecil untuk dinyatakan sebagai Single, hasilnya menjadi nol positif atau nol negatif. Double Jika nilai terlalu besar untuk diwakili sebagai Single, hasilnya menjadi tak terbatas positif atau tak terbatas negatif. Jika nilainya Double adalah NaN, hasilnya juga NaN.

  • Untuk konversi dari Single atau Double ke Decimal, nilai sumber dikonversi ke Decimal representasi dan dibulatkan ke angka terdekat setelah tempat desimal ke-28 jika diperlukan. Jika nilai sumber terlalu kecil untuk diwakili sebagai Decimal, hasilnya menjadi nol. Jika nilai sumber adalah NaN, tak terbatas, atau terlalu besar untuk direpresentasikan sebagai Decimal, System.OverflowException pengecualian akan dilemparkan.

  • Untuk konversi dari Double ke Single, nilai dibulatkan Double ke nilai terdekat Single . Double Jika nilai terlalu kecil untuk dinyatakan sebagai Single, hasilnya menjadi nol positif atau nol negatif. Double Jika nilai terlalu besar untuk diwakili sebagai Single, hasilnya menjadi tak terbatas positif atau tak terbatas negatif. Jika nilainya Double adalah NaN, hasilnya juga NaN.

Konversi Referensi

Jenis referensi dapat dikonversi ke jenis dasar, dan sebaliknya. Konversi dari jenis dasar ke jenis yang lebih turunan hanya berhasil pada waktu proses jika nilai yang dikonversi adalah nilai null, jenis turunan itu sendiri, atau jenis yang lebih turunan.

Jenis kelas dan antarmuka dapat dilemparkan ke dan dari jenis antarmuka apa pun. Konversi antara jenis dan jenis antarmuka hanya berhasil pada run time jika jenis aktual yang terlibat memiliki pewarisan atau hubungan implementasi. Karena jenis antarmuka akan selalu berisi instans jenis yang berasal dari Object, jenis antarmuka juga selalu dapat dilemparkan ke dan dari Object.

Nota. Ini bukan kesalahan untuk mengonversi NotInheritable kelas ke dan dari antarmuka yang tidak diterapkannya karena kelas yang mewakili kelas COM mungkin memiliki implementasi antarmuka yang tidak diketahui sampai run time.

Jika konversi referensi gagal pada waktu proses, System.InvalidCastException pengecualian akan dilemparkan.

Konversi Varians Referensi

Antarmuka atau delegasi generik mungkin memiliki parameter jenis varian yang memungkinkan konversi antara varian jenis yang kompatibel. Oleh karena itu, pada runtime konversi dari jenis kelas atau jenis antarmuka ke jenis antarmuka yang kompatibel dengan jenis antarmuka yang diwarisi dari atau diimplementasikan akan berhasil. Demikian pula, jenis delegasi dapat ditransmisikan ke dan dari jenis delegasi yang kompatibel dengan varian. Misalnya, jenis delegasi

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

akan memungkinkan konversi dari F(Of Object, Integer) ke F(Of String, Integer). Artinya, delegasi F yang mengambil Object dapat digunakan dengan aman sebagai delegasi F yang mengambil String. Ketika delegasi dipanggil, metode target akan mengharapkan objek, dan string adalah objek.

Delegasi generik atau jenis S(Of S1,...,Sn) antarmuka dikatakan kompatibel dengan varian dengan antarmuka generik atau jenis T(Of T1,...,Tn) delegasi jika:

  • S dan T keduanya dibangun dari jenis U(Of U1,...,Un)generik yang sama .

  • Untuk setiap parameter Uxjenis :

    • Jika parameter jenis dideklarasikan tanpa varians, maka Sx dan Tx harus jenis yang sama.

    • Jika parameter jenis dideklarasikan In , maka harus ada konversi parameter identitas, default, referensi, array, atau jenis yang melebar dari Sx ke Tx.

    • Jika parameter jenis dideklarasikan Out , maka harus ada konversi parameter identitas, default, referensi, array, atau jenis yang melebar dari Tx ke Sx.

Saat mengonversi dari kelas ke antarmuka generik dengan parameter jenis varian, jika kelas mengimplementasikan lebih dari satu antarmuka yang kompatibel dengan varian, konversi bersifat ambigu jika tidak ada konversi non-varian. Contohnya:

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

Konversi Delegasi Anonim

Ketika ekspresi diklasifikasikan sebagai metode lambda diklasifikasikan ulang sebagai nilai dalam konteks di mana tidak ada jenis target (misalnya, Dim x = Function(a As Integer, b As Integer) a + b), atau di mana jenis target bukan jenis delegasi, jenis ekspresi yang dihasilkan adalah jenis delegasi anonim yang setara dengan tanda tangan metode lambda. Jenis delegasi anonim ini memiliki konversi ke jenis delegasi yang kompatibel: jenis delegasi yang kompatibel adalah jenis delegasi apa pun yang dapat dibuat menggunakan ekspresi pembuatan delegasi dengan metode jenis Invoke delegasi anonim sebagai parameter. Contohnya:

' 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

Perhatikan bahwa jenis System.Delegate dan System.MulticastDelegate tidak dianggap sebagai jenis delegasi (meskipun semua jenis delegasi mewarisinya). Selain itu, perhatikan bahwa konversi dari jenis delegasi anonim ke jenis delegasi yang kompatibel bukan konversi referensi.

Konversi Array

Selain konversi yang didefinisikan pada array berdasarkan fakta bahwa mereka adalah jenis referensi, beberapa konversi khusus ada untuk array.

Untuk dua jenis A dan B, jika keduanya adalah jenis referensi atau parameter jenis yang tidak dikenal sebagai jenis nilai, dan jika A memiliki referensi, array, atau konversi parameter jenis ke B, konversi ada dari array jenis A ke array jenis B dengan peringkat yang sama. Hubungan ini dikenal sebagai kovarians array. Kovarians array khususnya berarti bahwa elemen array yang jenis elemennya sebenarnya mungkin merupakan B elemen dari array yang jenis elemennya adalah A, asalkan dan AB merupakan jenis referensi dan yang B memiliki konversi referensi atau konversi array ke A. Dalam contoh berikut, pemanggilan kedua menyebabkan System.ArrayTypeMismatchException pengecualian dilemparkan karena jenis elemen aktual adalah bString, bukan Object:F

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

Karena kovarians array, penugasan ke elemen array jenis referensi menyertakan pemeriksaan run-time yang memastikan bahwa nilai yang ditetapkan ke elemen array sebenarnya dari jenis yang diizinkan.

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

Dalam contoh ini, penugasan ke array(i) dalam metode Fill secara implisit menyertakan pemeriksaan run-time yang memastikan bahwa objek yang dirujuk oleh variabel value adalah Nothing atau instans jenis yang kompatibel dengan jenis elemen array arrayaktual . Dalam metode Main, dua pemanggilan metode Fill pertama berhasil, tetapi pemanggilan ketiga menyebabkan System.ArrayTypeMismatchException pengecualian dilemparkan setelah menjalankan penugasan pertama ke array(i). Pengecualian terjadi karena Integer tidak dapat disimpan dalam String array.

Jika salah satu jenis elemen array adalah parameter jenis yang jenisnya ternyata merupakan jenis nilai saat runtime, System.InvalidCastException pengecualian akan dilemparkan. Contohnya:

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

Konversi juga ada antara array jenis enumerasi dan array dari jenis yang mendasar jenis enumerasi atau array dari jenis enumerasi lain dengan jenis yang mendasar yang sama, asalkan array memiliki peringkat yang sama.

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

Dalam contoh ini, array dikonversi Color ke dan dari array , ByteColorjenis yang mendasar. Konversi ke array Integer, namun, akan menjadi kesalahan karena Integer bukan jenis yang mendasar dari Color.

Array peringkat-1 jenis A() juga memiliki konversi array ke jenis IList(Of B)antarmuka koleksi , , IReadOnlyList(Of B)ICollection(Of B), IReadOnlyCollection(Of B) dan IEnumerable(Of B) ditemukan di System.Collections.Generic, selama salah satu hal berikut ini benar:

  • A dan B merupakan jenis referensi atau parameter jenis yang tidak dikenal sebagai jenis nilai; dan A memiliki referensi yang melebar, array atau jenis konversi parameter ke B; atau
  • A dan B keduanya adalah jenis enumerasi dari jenis yang mendasar yang sama; atau
  • salah satu dari A dan B adalah jenis enumerasi, dan yang lainnya adalah jenis yang mendasar.

Array jenis A apa pun dengan peringkat apa pun juga memiliki konversi array ke jenis IListantarmuka koleksi non-generik , ICollection dan IEnumerable ditemukan di System.Collections.

Dimungkinkan untuk melakukan iterasi melalui antarmuka yang dihasilkan menggunakan For Each, atau melalui memanggil metode secara GetEnumerator langsung. Dalam kasus array peringkat-1 dikonversi bentuk generik atau non-generik dari IList atau ICollection, dimungkinkan juga untuk mendapatkan elemen berdasarkan indeks. Dalam kasus array peringkat-1 yang dikonversi ke bentuk IListgenerik atau non-generik , dimungkinkan juga untuk mengatur elemen menurut indeks, tunduk pada pemeriksaan kovariansi array runtime yang sama seperti yang dijelaskan di atas. Perilaku semua metode antarmuka lainnya tidak ditentukan oleh spesifikasi bahasa VB; hingga runtime yang mendasarinya.

Konversi Tipe Nilai

Nilai jenis nilai dapat dikonversi ke salah satu jenis referensi dasarnya atau jenis antarmuka yang diterapkannya melalui proses yang disebut tinju. Ketika nilai jenis nilai dikotak, nilai disalin dari lokasi tempat nilai berada ke tumpukan .NET Framework. Referensi ke lokasi ini pada tumpukan kemudian dikembalikan dan dapat disimpan dalam variabel jenis referensi. Referensi ini juga disebut sebagai instans kotak dari jenis nilai. Instans berkotak memiliki semantik yang sama dengan jenis referensi alih-alih jenis nilai.

Jenis nilai kotak dapat dikonversi kembali ke jenis nilai aslinya melalui proses yang disebut pembukaan kotak. Saat jenis nilai kotak tidak dikotak, nilai disalin dari tumpukan ke lokasi variabel. Sejak saat itu, ia berulah seolah-olah itu adalah jenis nilai. Saat membuka kotak jenis nilai, nilai harus berupa nilai null atau instans jenis nilai. Jika tidak, System.InvalidCastException pengecualian akan dilemparkan. Jika nilai adalah instans dari jenis enumerasi, nilai tersebut juga dapat dikotakkan ke jenis yang mendasar jenis enumerasi atau jenis enumerasi lain yang memiliki jenis yang mendasar yang sama. Nilai null diperlakukan seolah-olah itu harfiah Nothing.

Untuk mendukung jenis nilai nullable dengan baik, jenis System.Nullable(Of T) nilai diperlakukan khusus saat melakukan tinju dan membuka kotak. Tinju nilai jenis Nullable(Of T) menghasilkan nilai berkotak jenis T jika properti nilai HasValue adalah True atau nilai Nothing jika properti nilai HasValue adalah False. Membatalkan kotak nilai jenis T untuk Nullable(Of T) menghasilkan instans Nullable(Of T) yang propertinya Value adalah nilai kotak dan yang propertinya HasValue adalah True. Nilai Nothing dapat dikotak ke untuk Nullable(Of T) apa pun T dan menghasilkan nilai yang propertinya HasValue adalah False. Karena jenis nilai kotak bersifat seperti jenis referensi, dimungkinkan untuk membuat beberapa referensi ke nilai yang sama. Untuk jenis primitif dan jenis enumerasi, ini tidak relevan karena instans jenis tersebut tidak dapat diubah. Artinya, tidak mungkin untuk memodifikasi instans kotak dari jenis tersebut, sehingga tidak mungkin untuk mengamati fakta bahwa ada beberapa referensi ke nilai yang sama.

Struktur, di sisi lain, mungkin dapat diubah jika variabel instansnya dapat diakses atau jika metode atau propertinya memodifikasi variabel instansnya. Jika satu referensi ke struktur kotak digunakan untuk memodifikasi struktur, maka semua referensi ke struktur kotak akan melihat perubahan. Karena hasil ini mungkin tidak terduga, ketika nilai yang diketik seperti Object yang disalin dari satu lokasi ke jenis nilai kotak lain akan secara otomatis dikloning pada tumpukan alih-alih hanya menyalin referensi mereka. Contohnya:

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

Output dari program adalah:

Values: 0, 123
Refs: 123, 123

Penugasan ke bidang variabel val2 lokal tidak berdampak pada bidang variabel val1 lokal karena ketika kotak Struct1 ditetapkan ke val2, salinan nilai dibuat. Sebaliknya, penugasan ref2.Value = 123 memengaruhi objek yang dirujuk dan ref2 dirujukref1.

Nota. Penyalinan struktur tidak dilakukan untuk struktur kotak yang ditik karena System.ValueType tidak mungkin untuk terlambat mengikat dari System.ValueType.

Ada satu pengecualian untuk aturan yang tipe nilai kotaknya akan disalin pada penugasan. Jika referensi jenis nilai dalam kotak disimpan dalam jenis lain, referensi dalam tidak akan disalin. Contohnya:

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

Output dari program adalah:

Values: 123, 123

Ini karena nilai dalam kotak tidak disalin saat nilai disalin. Dengan demikian, keduanya val1.Value dan val2.Value memiliki referensi ke jenis nilai kotak yang sama.

Nota. Fakta bahwa jenis nilai dalam kotak tidak disalin adalah batasan dari sistem jenis .NET -- untuk memastikan bahwa semua jenis nilai dalam kotak disalin setiap kali nilai jenis Object disalin akan sangat mahal.

Seperti yang dijelaskan sebelumnya, jenis nilai kotak hanya dapat dibuka kotaknya ke jenis aslinya. Jenis primitif kotak, bagaimanapun, diperlakukan khusus ketika ditik sebagai Object. Mereka dapat dikonversi ke jenis primitif lainnya yang mereka miliki konversinya. Contohnya:

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

Biasanya, nilai 5 kotak Integer tidak dapat dikotak ke dalam Byte variabel. Namun, karena Integer dan Byte merupakan jenis primitif dan memiliki konversi, konversi diizinkan.

Penting untuk dicatat bahwa mengonversi jenis nilai ke antarmuka berbeda dari argumen generik yang dibatasi ke antarmuka. Saat mengakses anggota antarmuka pada parameter jenis yang dibatasi (atau metode panggilan pada Object), tinju tidak terjadi seperti saat jenis nilai dikonversi ke antarmuka dan anggota antarmuka diakses. Misalnya, antarmuka ICounter berisi metode Increment yang dapat digunakan untuk memodifikasi nilai. Jika ICounter digunakan sebagai batasan, implementasi metode dipanggil Increment dengan referensi ke variabel yang Increment dipanggil, bukan salinan kotak:

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

Panggilan pertama untuk Increment memodifikasi nilai dalam variabel x. Ini tidak setara dengan panggilan kedua ke Increment, yang memodifikasi nilai dalam salinan yang terkotak dari x. Dengan demikian, output program adalah:

0
1
1

Konversi Tipe Nilai Nullable

Jenis T nilai dapat mengonversi ke dan dari versi jenis yang dapat diubah ke null, T?. Konversi dari T? ke T memberikan System.InvalidOperationException pengecualian jika nilai yang dikonversi adalah Nothing. Selain itu, T? memiliki konversi ke jenis S jika T memiliki konversi intrinsik ke S. Dan jika S adalah jenis nilai, maka konversi intrinsik berikut ada antara T? dan S?:

  • Konversi klasifikasi yang sama (mempersempit atau melebar) dari T? ke S?.

  • Konversi klasifikasi yang sama (mempersempit atau melebar) dari T ke S?.

  • Konversi yang menyempit dari S? ke T.

Misalnya, konversi pelesiran intrinsik ada dari Integer? ke Long? karena konversi pelesiran intrinsik ada dari Integer ke Long:

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

Saat mengonversi dari T? ke S?, jika nilainya T? adalah Nothing, maka nilainya S? adalah Nothing. Saat mengonversi dari ke atau ke , jika nilai T? atau S? adalah Nothing, System.InvalidCastException pengecualian akan dilemparkan.ST?TS?

Karena perilaku jenis System.Nullable(Of T)yang mendasar , ketika jenis T? nilai nullable dikotak, hasilnya adalah nilai berkotak jenis T, bukan nilai berkotak jenis T?. Dan, sebaliknya, ketika membuka kotak ke jenis T?nilai nullable , nilai akan dibungkus oleh System.Nullable(Of T), dan Nothing akan dikotak ke nilai null jenis T?. Contohnya:

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

Efek samping dari perilaku ini adalah bahwa jenis T? nilai nullable tampaknya mengimplementasikan semua antarmuka T, karena mengonversi jenis nilai ke antarmuka mengharuskan jenis untuk dikotak. Akibatnya, T? dapat dikonversi ke semua antarmuka yang T dapat dikonversi. Namun, penting untuk dicatat bahwa jenis T? nilai nullable tidak benar-benar mengimplementasikan antarmuka T untuk tujuan pemeriksaan atau pantulan batasan generik. Contohnya:

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

Konversi String

Mengonversi Char menjadi String hasil dalam string yang karakter pertamanya adalah nilai karakter. Mengonversi String menjadi Char menghasilkan karakter yang nilainya adalah karakter pertama dari string. Mengonversi array menjadi CharString hasil dalam string yang karakternya adalah elemen array. Mengonversi String menjadi array Char hasil dalam array karakter yang elemennya adalah karakter string.

Konversi yang tepat antara String dan , , SByteByte, ULongLongShortUIntegerUShortInteger, Decimal, Single, Double, , Date, dan sebaliknya, berada di luar cakupan spesifikasi ini dan implementasi tergantung pada pengecualian satu detail.Boolean Konversi string selalu mempertimbangkan budaya lingkungan run-time saat ini. Dengan demikian, mereka harus dilakukan pada waktu proses.

Melebarkan Konversi

Melebarkan konversi tidak pernah meluap tetapi dapat mengakibatkan hilangnya presisi. Konversi berikut adalah konversi yang melebar:

Konversi Identitas/Default

  • Dari jenis ke dirinya sendiri.

  • Dari jenis delegasi anonim yang dihasilkan untuk reklasifikasi metode lambda ke jenis delegasi apa pun dengan tanda tangan yang identik.

  • Dari literal Nothing ke jenis.

Konversi numerik

  • Dari Byte ke UShort, Short, UInteger, Integer, ULong, Long, Decimal, Single, atau Double.

  • Dari SByte ke Short, Integer, Long, Decimal, Single, atau Double.

  • Dari UShort ke UInteger, Integer, ULong, Long, Decimal, Single, atau Double.

  • Dari Short ke Integer, Long, Decimal, Single atau Double.

  • Dari UInteger ke ULong, Long, Decimal, Single, atau Double.

  • Dari Integer ke Long, Decimal, Single atau Double.

  • Dari ULong ke Decimal, Single, atau Double.

  • Dari Long ke Decimal, Single atau Double.

  • Dari Decimal ke Single atau Double.

  • Dari Single ke Double.

  • Dari harfiah 0 hingga jenis enumerasi. (Catatan. Konversi dari 0 ke jenis enumerasi apa pun melebar untuk menyederhanakan bendera pengujian. Misalnya, jika Values adalah jenis enumerasi dengan nilai One, Anda dapat menguji variabel v jenis Values dengan mengatakan (v And Values.One) = 0.)

  • Dari jenis enumerasi hingga jenis numerik yang mendasarnya, atau ke jenis numerik yang mendasar jenis numeriknya memiliki konversi yang melebar.

  • Dari ekspresi konstan jenis ULong, , Long, UInteger, UShortInteger, Short, Byte, atau SByte ke jenis yang lebih sempit, asalkan nilai ekspresi konstanta berada dalam rentang jenis tujuan. (Catatan. Konversi dari atau ke , atau ke atau , atau Decimal ke Single atau Double dapat menyebabkan hilangnya presisi, tetapi tidak akan pernah menyebabkan hilangnya besaran.DoubleSingleLongULongSingleIntegerUInteger Konversi numerik lain yang melebar tidak pernah kehilangan informasi apa pun.)

Konversi referensi

  • Dari jenis referensi ke jenis dasar.

  • Dari jenis referensi ke jenis antarmuka, asalkan jenis mengimplementasikan antarmuka atau antarmuka yang kompatibel dengan varian.

  • Dari jenis antarmuka ke Object.

  • Dari jenis antarmuka hingga jenis antarmuka yang kompatibel dengan varian.

  • Dari jenis delegasi ke jenis delegasi yang kompatibel dengan varian. (Catatan. Banyak konversi referensi lainnya tersirat oleh aturan ini. Misalnya, delegasi anonim adalah jenis referensi yang mewarisi dari System.MulticastDelegate; jenis array adalah jenis referensi yang mewarisi dari System.Array; jenis anonim adalah jenis referensi yang mewarisi dari System.Object.)

Konversi Delegasi Anonim

  • Dari jenis delegasi anonim yang dihasilkan untuk reklasifikasi metode lambda ke jenis delegasi yang lebih luas.

Konversi array

  • Dari jenis S array dengan jenis Se elemen ke jenis array dengan jenis TTeelemen , asalkan semua hal berikut ini benar:

    • S dan T hanya berbeda dalam jenis elemen.

    • Keduanya Se dan Te merupakan jenis referensi atau merupakan parameter jenis yang diketahui sebagai jenis referensi.

    • Referensi yang melebar, array, atau konversi parameter jenis ada dari Se ke Te.

  • Dari jenis S array dengan jenis Se elemen enumerasi ke jenis T array dengan jenis Teelemen , asalkan semua yang berikut ini benar:

    • S dan T hanya berbeda dalam jenis elemen.

    • Te adalah jenis yang mendasar dari Se.

  • Dari jenis S array peringkat 1 dengan jenis Seelemen enumerasi , ke System.Collections.Generic.IList(Of Te), , IReadOnlyList(Of Te)ICollection(Of Te), IReadOnlyCollection(Of Te), dan IEnumerable(Of Te), asalkan salah satu hal berikut ini benar:

    • Keduanya Se dan Te merupakan jenis referensi atau merupakan parameter jenis yang dikenal sebagai jenis referensi, dan referensi yang melebar, array, atau jenis konversi parameter ada dari Se ke Te; atau

    • Te adalah jenis yang mendasar dari Se; atau

    • Te identik dengan Se

Konversi Tipe Nilai

  • Dari jenis nilai hingga jenis dasar.

  • Dari jenis nilai hingga jenis antarmuka yang diterapkan jenis.

Konversi Tipe Nilai Yang Dapat Diubah Ke null

  • Dari jenis T ke jenis T?.

  • Dari jenis T? ke jenis S?, di mana ada konversi yang melebar dari jenis T ke jenis S.

  • Dari jenis T ke jenis S?, di mana ada konversi yang melebar dari jenis T ke jenis S.

  • Dari jenis T? hingga jenis antarmuka yang diterapkan jenis T .

Konversi string

  • Dari Char ke String.

  • Dari Char() ke String.

Konversi Parameter Jenis

  • Dari parameter jenis ke Object.

  • Dari parameter jenis hingga batasan jenis antarmuka atau varian antarmuka apa pun yang kompatibel dengan batasan jenis antarmuka.

  • Dari parameter jenis hingga antarmuka yang diimplementasikan oleh batasan kelas.

  • Dari parameter jenis hingga varian antarmuka yang kompatibel dengan antarmuka yang diimplementasikan oleh batasan kelas.

  • Dari parameter jenis hingga batasan kelas, atau jenis dasar batasan kelas.

  • Dari parameter T jenis hingga batasan Txparameter jenis , atau apa pun Tx memiliki konversi yang melebar.

Konversi yang Menyempit

Konversi yang mempersempit adalah konversi yang tidak dapat dibuktikan untuk selalu berhasil, konversi yang diketahui mungkin kehilangan informasi, dan konversi di seluruh domain jenis yang cukup berbeda untuk mempersempit notasi. Konversi berikut diklasifikasikan sebagai konversi yang mempersempit:

Konversi Boolean

  • Dari Boolean ke Byte, SByte, UShort, Short, UInteger, Integer, ULong, Long, Decimal, , Single, atau Double.

  • Dari Byte, SByte, UShort, Short, UInteger, Integer, ULong, Long, Decimal, , Single, atau Double ke Boolean.

Konversi numerik

  • Dari Byte ke SByte.

  • Dari SByte ke Byte, UShort, UInteger, atau ULong.

  • Dari UShort ke Byte, SByte, atau Short.

  • Dari Short ke Byte, SByte, UShort, UInteger, atau ULong.

  • Dari UInteger ke Byte, SByte, UShort, Short, atau Integer.

  • Dari Integer ke Byte, SByte, UShort, Short, UInteger, atau ULong.

  • Dari ULong ke Byte, SByte, UShort, Short, UInteger, Integer, atau Long.

  • Dari Long ke Byte, SByte, UShort, Short, UInteger, Integer, atau ULong.

  • Dari Decimal ke Byte, SByte, UShort, Short, UInteger, Integer, ULong, atau Long.

  • Dari Single ke Byte, SByte, UShort, Short, UInteger, Integer, ULong, Long, atau Decimal.

  • Dari Double ke Byte, SByte, UShort, Short, UInteger, Integer, ULong, Long, , Decimal, atau Single.

  • Dari jenis numerik ke jenis enumerasi.

  • Dari jenis enumerasi ke jenis numerik yang mendasar jenis numeriknya memiliki konversi yang menyempit ke.

  • Dari jenis enumerasi ke jenis enumerasi lain.

Konversi referensi

  • Dari jenis referensi ke jenis yang lebih turunan.

  • Dari jenis kelas ke jenis antarmuka, asalkan jenis kelas tidak mengimplementasikan jenis antarmuka atau varian jenis antarmuka yang kompatibel dengannya.

  • Dari jenis antarmuka ke jenis kelas.

  • Dari jenis antarmuka ke jenis antarmuka lain, asalkan tidak ada hubungan warisan antara dua jenis dan asalkan tidak kompatibel dengan varian.

Konversi Delegasi Anonim

  • Dari jenis delegasi anonim yang dihasilkan untuk reklasifikasi metode lambda ke jenis delegasi yang lebih sempit.

Konversi array

  • Dari jenis S array dengan jenis Seelemen , ke jenis array dengan jenis TTeelemen , asalkan semua hal berikut ini benar:

    • S dan T hanya berbeda dalam jenis elemen.
    • Keduanya Se dan Te merupakan jenis referensi atau merupakan parameter jenis yang tidak diketahui sebagai jenis nilai.
    • Konversi parameter referensi, array, atau jenis yang menyempit ada dari Se ke Te.
  • Dari jenis S array dengan jenis Se elemen ke jenis T array dengan jenis Teelemen enumerasi , asalkan semua yang berikut ini benar:

    • S dan T hanya berbeda dalam jenis elemen.
    • Se adalah jenis yang mendasar dari Te , atau keduanya adalah jenis enumerasi yang berbeda yang memiliki jenis yang mendasar yang sama.
  • Dari jenis S array peringkat 1 dengan jenis Seelemen enumerasi , ke IList(Of Te), , IReadOnlyList(Of Te)ICollection(Of Te), IReadOnlyCollection(Of Te) dan IEnumerable(Of Te), asalkan salah satu hal berikut ini benar:

    • Keduanya Se dan Te merupakan jenis referensi atau merupakan parameter jenis yang dikenal sebagai jenis referensi, dan referensi, array, atau konversi parameter jenis yang menyempit ada dari Se ke Te; atau
    • Se adalah jenis yang mendasar dari Te, atau keduanya adalah jenis enumerasi yang berbeda yang memiliki jenis yang mendasar yang sama.

Konversi jenis nilai

  • Dari jenis referensi ke jenis nilai yang lebih turunan.

  • Dari jenis antarmuka hingga jenis nilai, asalkan jenis nilai mengimplementasikan jenis antarmuka.

Konversi Tipe Nilai Yang Dapat Diubah Ke null

  • Dari jenis T? ke jenis T.

  • Dari jenis T? ke jenis S?, di mana ada konversi yang mempersempit dari jenis T ke jenis S.

  • Dari jenis T ke jenis S?, di mana ada konversi yang mempersempit dari jenis T ke jenis S.

  • Dari jenis S? ke jenis T, di mana ada konversi dari jenis S ke jenis T.

Konversi string

  • Dari String ke Char.

  • Dari String ke Char().

  • Dari String ke Boolean dan dari Boolean ke String.

  • Konversi antara dan , , , , , , Integer, ULong, Long, Decimal, Single, atau Double. UIntegerUShortShortSByteByteString

  • Dari String ke Date dan dari Date ke String.

Konversi Parameter Jenis

  • Dari Object ke parameter jenis.

  • Dari parameter jenis ke jenis antarmuka, asalkan parameter jenis tidak dibatasi ke antarmuka tersebut atau dibatasi ke kelas yang mengimplementasikan antarmuka tersebut.

  • Dari jenis antarmuka hingga parameter jenis.

  • Dari parameter jenis hingga jenis turunan dari batasan kelas.

  • Dari parameter T jenis hingga apa pun batasan Tx parameter jenis memiliki konversi yang mempersempit.

Konversi Parameter Jenis

Konversi parameter jenis ditentukan oleh batasan, jika ada, dimasukkan ke dalamnya. Parameter T jenis selalu dapat dikonversi ke dirinya sendiri, ke dan dari Object, dan ke dan dari jenis antarmuka apa pun. Perhatikan bahwa jika jenisnya T adalah jenis nilai pada run-time, mengonversi dari T ke Object atau jenis antarmuka akan menjadi konversi tinju dan mengonversi dari Object atau jenis antarmuka menjadi T konversi pembuka kotak. Parameter jenis dengan batasan C kelas menentukan konversi tambahan dari parameter jenis ke C dan kelas dasarnya, dan sebaliknya. Parameter T jenis dengan batasan Tx parameter jenis menentukan konversi ke Tx dan apa pun Tx yang dikonversi.

Array yang jenis elemennya adalah parameter jenis dengan batasan I antarmuka memiliki konversi array kovarian yang sama dengan array yang jenis elemennya adalah I, asalkan parameter jenis juga memiliki Class batasan kelas atau (karena hanya jenis elemen array referensi yang dapat kovarian). Array yang jenis elemennya adalah parameter jenis dengan batasan C kelas memiliki konversi array kovarian yang sama dengan array yang jenis elemennya adalah C.

Aturan konversi di atas tidak mengizinkan konversi dari parameter jenis yang tidak dibatasi ke jenis non-antarmuka, yang mungkin mengejutkan. Alasan untuk ini adalah untuk mencegah kebingungan tentang semantik konversi tersebut. Misalnya, pertimbangkan deklarasi berikut:

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

Jika konversi ke TInteger diizinkan, seseorang mungkin dengan mudah mengharapkan itu X(Of Integer).F(7) akan mengembalikan 7L. Namun, itu tidak akan, karena konversi numerik hanya dipertimbangkan ketika jenis diketahui numerik pada waktu kompilasi. Untuk memperjelas semantik, contoh di atas harus ditulis:

Class X(Of T)
    Public Shared Function F(t As T) As Long
        Return CLng(CObj(t))    ' OK, conversions permitted
    End Function
End Class

Konversi User-Defined

Konversi intrinsik adalah konversi yang ditentukan oleh bahasa (yaitu tercantum dalam spesifikasi ini), sementara konversi yang ditentukan pengguna ditentukan oleh kelebihan beban CType operator. Saat mengonversi antar jenis, jika tidak ada konversi intrinsik yang berlaku, konversi yang ditentukan pengguna akan dipertimbangkan. Jika ada konversi yang ditentukan pengguna yang paling spesifik untuk jenis sumber dan target, konversi yang ditentukan pengguna akan digunakan. Jika tidak, hasil kesalahan waktu kompilasi. Konversi yang paling spesifik adalah yang operannya "paling dekat" dengan jenis sumber dan yang jenis hasilnya "paling dekat" dengan jenis target. Saat menentukan konversi yang ditentukan pengguna untuk digunakan, konversi pelesiran yang paling spesifik akan digunakan; jika tidak ada konversi yang paling spesifik, konversi penyempitan yang paling spesifik akan digunakan. Jika tidak ada konversi penyempitan yang paling spesifik, maka konversi tidak ditentukan dan terjadi kesalahan waktu kompilasi.

Bagian berikut mencakup bagaimana konversi yang paling spesifik ditentukan. Mereka menggunakan istilah berikut:

Jika konversi pelesiran intrinsik ada dari jenis A ke jenis B, dan jika tidak atau AB antarmuka, maka Adilibatkan oleh B, danAB mencakup.

Jenis yang paling mencakup dalam sekumpulan jenis adalah satu jenis yang mencakup semua jenis lain dalam set. Jika tidak ada jenis tunggal yang mencakup semua jenis lainnya, maka set tidak memiliki jenis yang paling mencakup. Dalam istilah intuitif, jenis yang paling mencakup adalah jenis "terbesar" dalam set -- satu jenis yang masing-masing jenisnya dapat dikonversi melalui konversi yang melebar.

Jenis yang paling mencakup dalam sekumpulan jenis adalah satu jenis yang disertakan oleh semua jenis lain dalam set. Jika tidak ada jenis tunggal yang dililit oleh semua jenis lainnya, maka set tidak memiliki jenis yang paling dilirik. Dalam istilah intuitif, jenis yang paling mencakup adalah jenis "terkecil" dalam set -- satu jenis yang dapat dikonversi ke masing-masing jenis lainnya melalui konversi yang menyempit.

Saat mengumpulkan konversi yang ditentukan pengguna kandidat untuk jenis T?, operator konversi yang ditentukan pengguna yang ditentukan oleh T digunakan sebagai gantinya. Jika jenis yang dikonversi ke juga merupakan jenis nilai nullable, maka salah Tsatu operator konversi yang ditentukan pengguna yang hanya melibatkan jenis nilai yang tidak dapat diubah ke null diangkat. Operator konversi dari T ke S diangkat menjadi konversi dari T? ke S? dan dievaluasi dengan mengonversi T? ke T, jika perlu, lalu mengevaluasi operator konversi yang ditentukan pengguna dari T ke S dan kemudian mengonversi S ke S?, jika perlu. Namun, jika nilai yang dikonversi adalah Nothing, operator konversi yang diangkat akan dikonversi langsung menjadi nilai yang ditik Nothing sebagai S?. Contohnya:

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

Saat menyelesaikan konversi, operator konversi yang ditentukan pengguna selalu lebih disukai daripada operator konversi yang diangkat. Contohnya:

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

Pada run-time, mengevaluasi konversi yang ditentukan pengguna dapat melibatkan hingga tiga langkah:

  1. Pertama, nilai dikonversi dari jenis sumber ke jenis operand menggunakan konversi intrinsik, jika perlu.

  2. Kemudian, konversi yang ditentukan pengguna dipanggil.

  3. Terakhir, hasil konversi yang ditentukan pengguna dikonversi ke jenis target menggunakan konversi intrinsik, jika perlu.

Penting untuk dicatat bahwa evaluasi konversi yang ditentukan pengguna tidak akan pernah melibatkan lebih dari satu operator konversi yang ditentukan pengguna.

Konversi Pelesiran Paling Spesifik

Menentukan operator konversi pelesiran yang paling spesifik yang ditentukan pengguna antara dua jenis dicapai menggunakan langkah-langkah berikut:

  1. Pertama, semua operator konversi kandidat dikumpulkan. Operator konversi kandidat adalah semua operator konversi yang melebar yang ditentukan pengguna dalam jenis sumber dan semua operator konversi yang ditentukan pengguna dalam jenis target.

  2. Kemudian, semua operator konversi yang tidak berlaku dihapus dari set. Operator konversi berlaku untuk jenis sumber dan jenis target jika ada operator konversi pelesiran intrinsik dari jenis sumber ke jenis operand dan ada operator konversi pelesiran intrinsik dari hasil operator ke jenis target. Jika tidak ada operator konversi yang berlaku, maka tidak ada konversi pelesiran yang paling spesifik.

  3. Kemudian, jenis sumber paling spesifik dari operator konversi yang berlaku ditentukan:

    • Jika salah satu operator konversi mengonversi langsung dari jenis sumber, maka jenis sumber adalah jenis sumber yang paling spesifik.

    • Jika tidak, jenis sumber yang paling spesifik adalah jenis yang paling mencakup dalam kumpulan gabungan jenis sumber operator konversi. Jika tidak ada jenis yang paling luas dapat ditemukan, maka tidak ada konversi pelesiran yang paling spesifik.

  4. Kemudian, jenis target paling spesifik dari operator konversi yang berlaku ditentukan:

    • Jika salah satu operator konversi mengonversi langsung ke jenis target, maka jenis target adalah jenis target yang paling spesifik.

    • Jika tidak, jenis target yang paling spesifik adalah jenis yang paling mencakup dalam kumpulan gabungan jenis target operator konversi. Jika tidak ada jenis yang paling mencakup yang dapat ditemukan, maka tidak ada konversi pelesiran yang paling spesifik.

  5. Kemudian, jika tepat satu operator konversi dikonversi dari jenis sumber yang paling spesifik ke jenis target yang paling spesifik, maka ini adalah operator konversi yang paling spesifik. Jika ada lebih dari satu operator tersebut, maka tidak ada konversi pelebar yang paling spesifik.

Konversi Penyempitan Paling Spesifik

Menentukan operator konversi penyempitan yang paling spesifik yang ditentukan pengguna antara dua jenis dicapai menggunakan langkah-langkah berikut:

  1. Pertama, semua operator konversi kandidat dikumpulkan. Operator konversi kandidat adalah semua operator konversi yang ditentukan pengguna dalam jenis sumber dan semua operator konversi yang ditentukan pengguna dalam jenis target.

  2. Kemudian, semua operator konversi yang tidak berlaku dihapus dari set. Operator konversi berlaku untuk jenis sumber dan jenis target jika ada operator konversi intrinsik dari jenis sumber ke jenis operand dan ada operator konversi intrinsik dari hasil operator ke jenis target. Jika tidak ada operator konversi yang berlaku, maka tidak ada konversi penyempitan yang paling spesifik.

  3. Kemudian, jenis sumber paling spesifik dari operator konversi yang berlaku ditentukan:

    • Jika salah satu operator konversi mengonversi langsung dari jenis sumber, maka jenis sumber adalah jenis sumber yang paling spesifik.

    • Jika tidak, jika salah satu operator konversi mengonversi dari jenis yang mencakup jenis sumber, maka jenis sumber yang paling spesifik adalah jenis yang paling mencakup dalam kumpulan gabungan jenis sumber dari operator konversi tersebut. Jika tidak ada jenis yang paling mencakup yang dapat ditemukan, maka tidak ada konversi penyempitan yang paling spesifik.

    • Jika tidak, jenis sumber yang paling spesifik adalah jenis yang paling mencakup dalam kumpulan gabungan jenis sumber operator konversi. Jika tidak ada jenis yang paling mencakup yang dapat ditemukan, maka tidak ada konversi penyempitan yang paling spesifik.

  4. Kemudian, jenis target paling spesifik dari operator konversi yang berlaku ditentukan:

    • Jika salah satu operator konversi mengonversi langsung ke jenis target, maka jenis target adalah jenis target yang paling spesifik.

    • Jika tidak, jika salah satu operator konversi mengonversi ke jenis yang disertakan oleh jenis target, maka jenis target yang paling spesifik adalah jenis yang paling mencakup dalam kumpulan gabungan jenis sumber dari operator konversi tersebut. Jika tidak ada jenis yang paling mencakup yang dapat ditemukan, maka tidak ada konversi penyempitan yang paling spesifik.

    • Jika tidak, jenis target yang paling spesifik adalah jenis yang paling mencakup dalam kumpulan gabungan jenis target operator konversi. Jika tidak ada jenis yang paling mencakup yang dapat ditemukan, maka tidak ada konversi penyempitan yang paling spesifik.

  5. Kemudian, jika tepat satu operator konversi dikonversi dari jenis sumber yang paling spesifik ke jenis target yang paling spesifik, maka ini adalah operator konversi yang paling spesifik. Jika ada lebih dari satu operator tersebut, maka tidak ada konversi penyempitan yang paling spesifik.

Konversi Asli

Beberapa konversi diklasifikasikan sebagai konversi asli karena didukung secara asli oleh .NET Framework. Konversi ini adalah konversi yang dapat dioptimalkan melalui penggunaan DirectCast operator konversi dan TryCast , serta perilaku khusus lainnya. Konversi yang diklasifikasikan sebagai konversi asli adalah: konversi identitas, konversi default, konversi referensi, konversi array, konversi jenis nilai, dan konversi parameter jenis.

Jenis Dominan

Mengingat sekumpulan jenis, sering kali diperlukan dalam situasi seperti inferensi jenis untuk menentukan jenis set yang dominan . Jenis dominan dari sekumpulan jenis ditentukan dengan terlebih dahulu menghapus jenis apa pun yang satu atau beberapa jenis lain tidak memiliki konversi implisit. Jika tidak ada jenis yang tersisa pada saat ini, tidak ada jenis dominan. Jenis dominan kemudian merupakan jenis yang paling mencakup jenis yang tersisa. Jika ada lebih dari satu jenis yang paling mencakup, maka tidak ada jenis dominan.