Bagikan melalui


Tuple (Visual Basic)

Dimulai dengan Visual Basic 2017, bahasa Visual Basic menawarkan dukungan bawaan untuk tuple yang membuat pembuatan tuple dan pengaksesan elemen tuple lebih mudah. Tuple adalah struktur data ringan yang memiliki angka dan urutan nilai tertentu. Saat membuat instans tuple, Anda menentukan angka dan jenis data dari setiap nilai (atau elemen). Misalnya, 2 tuple (atau sepasang) memiliki dua elemen. Yang pertama mungkin merupakan nilai Boolean, sementara yang kedua adalah String. Karena tuple memudahkan untuk menyimpan beberapa nilai dalam satu objek, tuple sering digunakan sebagai cara ringan untuk menampilkan beberapa nilai dari metode.

Penting

Dukungan tuple memerlukan jenis ValueTuple. Jika .NET Framework 4.7 tidak diinstal, Anda harus menambahkan paket NuGet System.ValueTuple, yang tersedia di Galeri NuGet. Tanpa paket ini, Anda mungkin mendapatkan kesalahan kompilasi yang mirip dengan, "Jenis yang telah ditentukan sebelumnya 'ValueTuple(Of,,,)' tidak ditentukan atau diimpor."

Membuat instans dan menggunakan tuple

Anda membuat instans tuple dengan menyertakan nilai yang dibatasi komanya dalam tanda kurung. Masing-masing nilai tersebut kemudian menjadi bidang tuple. Misalnya, kode berikut mendefinisikan tiga kali lipat (atau 3 tuple) dengan Date sebagai nilai pertamanya, String sebagai yang kedua, dan Boolean sebagai yang ketiga.

Dim holiday = (#07/04/2017#, "Independence Day", True)

Secara default, nama setiap bidang dalam tuple terdiri dari string Item bersama dengan posisi berbasis satu bidang di tuple. Untuk 3 tuple ini, bidang Date adalah Item1, bidang String adalah Item2, dan bidang Boolean adalah Item3. Contoh berikut menampilkan nilai bidang tuple yang dibuat di baris kode sebelumnya

Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' Output: 7/4/2017 12:00:00 AM Is Independence Day, a national holiday

Bidang tuple Visual Basic adalah baca-tulis; setelah Anda membuat instans tuple, Anda dapat memodifikasi nilainya. Contoh berikut memodifikasi dua dari tiga bidang tuple yang dibuat dalam contoh sebelumnya dan menampilkan hasilnya.

holiday.Item1 = #01/01/2018#
holiday.Item2 = "New Year's Day"
Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' Output: 1/1/2018 12:00:00 AM Is New Year's Day, a national holiday

Membuat instans dan menggunakan tuple bernama

Daripada menggunakan nama default untuk bidang tuple, Anda dapat membuat instans tuple bernama dengan menetapkan nama Anda sendiri ke elemen tuple. Bidang tuple kemudian dapat diakses dengan nama yang ditetapkan atau dengan nama defaultnya. Contoh berikut membuat instans 3 tuple yang sama seperti sebelumnya, kecuali bahwa itu secara eksplisit memberi nama bidang yang pertama EventDate, yang kedua Name, dan yang ketiga IsHoliday. Kemudian instans menampilkan nilai bidang, memodifikasinya, dan menampilkan nilai bidang lagi.

Dim holiday = (EventDate:=#07/04/2017#, Name:="Independence Day", IsHoliday:=True)
Console.WriteLine($"{holiday.EventDate} Is {holiday.Name}" +
                  $"{If(holiday.IsHoliday, ", a national holiday", String.Empty)}")
holiday.Item1 = #01/01/2018#
holiday.Item2 = "New Year's Day"
Console.WriteLine($"{holiday.Item1} is {holiday.Item2}" +
                  $"{If(holiday.Item3, ", a national holiday", String.Empty)}")
' The example displays the following output:
'   7/4/2017 12:00:00 AM Is Independence Day, a national holiday
'   1/1/2018 12:00:00 AM Is New Year's Day, a national holiday

Anda juga dapat menentukan nama tuple sebagai bagian dari deklarasi jenis suatu variabel, bidang, atau parameter:

Dim holiday As (EventDate As Date, Name As String, IsHoliday As Boolean) =
    (#07/04/2017#, "Independence Day", True)
Console.WriteLine(holiday.Name)
' Output: Independence Day

atau dalam jenis yang ditampilkan dari metode.

Ini sangat berguna saat memberikan tuple ke penginisialisasi koleksi; nama tuple dapat disediakan sebagai bagian dari deklarasi jenis koleksi:

Dim events As New List(Of (EventDate As Date, Name As String, IsHoliday As Boolean)) From {
    (#07/04/2017#, "Independence Day", True),
    (#04/22/2017#, "Earth Day", False)
}
Console.WriteLine(events(1).IsHoliday)
' Output: False

Nama elemen tuple yang disimpulkan

Dimulai dengan Visual Basic 15.3, Visual Basic dapat menyimpulkan nama elemen tuple; Anda tidak perlu menetapkannya secara eksplisit. Nama tuple yang disimpulkan berguna saat Anda menginisialisasi tuple dari sekumpulan variabel, dan Anda ingin nama elemen tuple sama dengan nama variabel.

Contoh berikut membuat stateInfo tuple yang berisi tiga elemen bernama secara eksplisit, state, stateName, dan capital. Perhatikan bahwa, dalam menamai elemen, pernyataan inisialisasi tuple hanya menetapkan elemen bernama nilai variabel bernama identik.

Const state As String = "MI"
Const stateName As String = "Michigan"
Const capital As String = "Lansing"
Dim stateInfo = (state:=state, stateName:=stateName, capital:=capital)
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.state}, Capital {stateInfo.capital}")
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

Karena elemen dan variabel memiliki nama yang sama, pengompilasi Visual Basic dapat menyimpulkan nama bidang, seperti yang ditunjukkan contoh berikut.

Const state As String = "MI"
Const stateName As String = "Michigan"
Const capital As String = "Lansing"
Dim stateInfo = (state, stateName, capital)
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.State}, Capital {stateInfo.capital}")
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

Untuk mengaktifkan nama elemen tuple yang disimpulkan, Anda harus menentukan versi pengompilasi Visual Basic untuk digunakan dalam file proyek Visual Basic (*.vbproj):

<PropertyGroup>
  <LangVersion>15.3</LangVersion>
</PropertyGroup>

Nomor versi dapat berupa versi pengompilasi Visual Basic apa pun yang dimulai dengan 15.3. Daripada mengkodekan secara permanen versi kompilator tertentu, Anda juga dapat menentukan "Terbaru" sebagai nilai LangVersion untuk dikompilasi dengan versi terbaru pengompilasi Visual Basic yang diinstal pada sistem Anda.

Untuk informasi selengkapnya, lihat mengatur versi bahasa Visual Basic.

Dalam beberapa kasus, pengompilasi Visual Basic tidak dapat menyimpulkan nama elemen tuple dari nama kandidat, dan bidang tuple hanya dapat direferensikan menggunakan nama defaultnya, seperti Item1, Item2, dll. Ini termasuk:

  • Nama kandidat sama dengan nama anggota tuple, seperti Item3, Rest, atau ToString.

  • Nama kandidat diduplikasi dalam tuple.

Ketika inferensi nama bidang gagal, Visual Basic tidak menghasilkan kesalahan pengompilasi, atau pengecualian yang ditampilkan saat run-time. Sebaliknya, bidang tuple harus dirujuk oleh nama yang telah ditentukan sebelumnya, seperti Item1 dan Item2.

Tuple versus struktur

Tuple Visual Basic adalah jenis nilai yang merupakan instans dari salah satu jenis generik System.ValueTuple. Misalnya, tuple holiday yang didefinisikan dalam contoh sebelumnya adalah instans struktur ValueTuple<T1,T2,T3>. Ini dirancang untuk menjadi kontainer ringan untuk data. Karena tuple bertujuan untuk memudahkan pembuatan objek dengan beberapa item data, tuple tidak memiliki beberapa fitur yang mungkin dimiliki struktur kustom. Ini termasuk:

  • Anggota kustom. Anda tidak dapat menentukan properti, metode, atau peristiwa Anda sendiri untuk tuple.

  • Validasi. Anda tidak dapat memvalidasi data yang ditetapkan ke bidang.

  • Ketetapan. Tuple Visual Basic dapat diubah. Sebaliknya, struktur kustom memungkinkan Anda mengontrol apakah instans dapat diubah atau tidak dapat diubah.

Jika anggota kustom, validasi properti dan bidang, atau kekekalan penting, Anda harus menggunakan pernyataan Structure Visual Basic untuk menentukan jenis nilai kustom.

Tuple Visual Basic mewarisi anggota dari jenis ValueTuple miliknya. Selain bidangnya, ini termasuk metode berikut:

Metode Deskripsi
CompareTo Membandingkan tuple saat ini dengan tuple lain dengan jumlah elemen yang sama.
Sama dengan Menentukan apakah tuple saat ini sama dengan tuple atau objek lain.
GetHashCode Menghitung kode hash untuk instans saat ini.
ToString Menampilkan representasi string dari tuple ini, yang mengambil bentuk (Item1, Item2...), di mana Item1 dan Item2 mewakili nilai bidang tuple.

Selain itu, jenis ValueTuple mengimplementasikan antarmuka IStructuralComparable dan IStructuralEquatable, yang memungkinkan Anda menentukan pembanding kustom.

Penugasan dan tuple

Visual Basic mendukung penugasan antara jenis tuple yang memiliki jumlah bidang yang sama. Jenis bidang dapat dikonversi jika salah satu hal berikut ini benar:

  • Bidang sumber dan target memiliki jenis yang sama.

  • Konversi pelebaran (atau implisit) dari jenis sumber ke jenis target ditentukan.

  • Option Strict adalah On, dan konversi yang mempersempit (atau eksplisit) dari jenis sumber ke jenis target ditentukan. Konversi ini dapat menampilkan pengecualian jika nilai sumber berada di luar rentang jenis target.

Konversi lain tidak dipertimbangkan untuk penugasan. Mari kita lihat jenis tugas yang diizinkan di antara jenis tuple.

Pertimbangkan variabel ini yang digunakan dalam contoh berikut:

' The number and field types of all these tuples are compatible. 
' The only difference Is the field names being used.
Dim unnamed = (42, "The meaning of life")
Dim anonymous = (16, "a perfect square")
Dim named = (Answer:=42, Message:="The meaning of life")
Dim differentNamed = (SecretConstant:=42, Label:="The meaning of life")

Dua variabel pertama, unnamed dan anonymous, tidak memiliki nama semantik yang disediakan untuk bidang. Nama bidangnya adalah default Item1 dan Item2. Dua variabel terakhir, named dan differentName memiliki nama bidang semantik. Perhatikan bahwa kedua tuple ini memiliki nama yang berbeda untuk bidang.

Keempat tuple ini memiliki jumlah bidang yang sama (disebut sebagai 'aritas'), dan jenis bidang tersebut identik. Oleh karena itu, semua tugas ini berfungsi:

' Assign named to unnamed.
named = unnamed

' Despite the assignment, named still has fields that can be referred to as 'answer' and 'message'.
Console.WriteLine($"{named.Answer}, {named.Message}")
' Output:  42, The meaning of life

' Assign unnamed to anonymous.
anonymous = unnamed
' Because of the assignment, the value of the elements of anonymous changed.
Console.WriteLine($"{anonymous.Item1}, {anonymous.Item2}")
' Output:   42, The meaning of life

' Assign one named tuple to the other.
named = differentNamed
' The field names are Not assigned. 'named' still has 'answer' and 'message' fields.
Console.WriteLine($"{named.Answer}, {named.Message}")
' Output:   42, The meaning of life

Perhatikan bahwa nama tuple tidak ditetapkan. Nilai bidang ditetapkan mengikuti urutan bidang dalam tuple.

Terakhir, perhatikan bahwa kita dapat menetapkan tuple named ke tuple conversion, meskipun bidang pertama named adalah Integer, dan bidang pertama conversion adalah Long. Penugasan ini berhasil karena mengonversi Integer ke Long adalah konversi yang melebar.

' Assign an (Integer, String) tuple to a (Long, String) tuple (using implicit conversion).
Dim conversion As (Long, String) = named
Console.WriteLine($"{conversion.Item1} ({conversion.Item1.GetType().Name}), " +
                  $"{conversion.Item2} ({conversion.Item2.GetType().Name})")
' Output:      42 (Int64), The meaning of life (String)

Tuple dengan jumlah bidang yang berbeda tidak dapat ditetapkan:

' Does not compile.
' VB30311: Value of type '(Integer, Integer, Integer)' cannot be converted
'          to '(Answer As Integer, Message As String)'
var differentShape = (1, 2, 3)
named = differentShape

Tuple sebagai nilai menampilkan metode

Metode hanya dapat menampilkan satu nilai. Namun, sering kali, Anda ingin panggilan metode untuk menampilkan beberapa nilai. Ada beberapa cara untuk mengatasi batasan ini:

  • Anda dapat membuat kelas atau struktur kustom yang properti atau bidangnya mewakili nilai yang ditampilkan oleh metode. Ini adalah solusi yang berat karena Anda menentukan jenis kustom yang tujuan satu-satunya adalah untuk mengambil nilai dari panggilan metode.

  • Anda dapat menampilkan satu nilai dari metode, dan menampilkan nilai yang tersisa dengan meneruskannya dengan merujuk ke metode. Ini melibatkan overhead instans variabel dan risiko secara tidak sengaja menimpa nilai variabel yang Anda lewati dengan referensi.

  • Anda dapat menggunakan tuple, yang menyediakan solusi ringan untuk mengambil beberapa nilai yang ditampilkan.

Misalnya, metode TryParse di .NET menampilkan nilai Boolean yang menunjukkan apakah operasi penguraian berhasil. Hasil operasi penguraian ditampilkan dalam variabel yang diteruskan oleh referensi ke metode. Biasanya, panggilan ke metode penguraian seperti Int32.TryParse terlihat seperti berikut:

Dim numericString As String = "123456"
Dim number As Integer
Dim result = Integer.TryParse(numericString, number)
Console.WriteLine($"{If(result, $"Success: {number:N0}", "Failure")}")
'      Output: Success: 123,456

Kita dapat menampilkan tuple dari operasi penguraian jika kita membungkus panggilan ke metode Int32.TryParse dalam metode kita sendiri. Dalam contoh berikut, NumericLibrary.ParseInteger memanggil metode Int32.TryParse dan menampilkan tuple bernama dengan dua elemen.

Imports System.Globalization

Public Module NumericLibrary
    Public Function ParseInteger(value As String) As (Success As Boolean, Number As Integer)
        Dim number As Integer
        Return (Integer.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, number), number)
    End Function
End Module

Anda kemudian dapat memanggil metode dengan kode seperti berikut:

Dim numericString As String = "123,456"
Dim result = ParseInteger(numericString)
Console.WriteLine($"{If(result.Success, $"Success: {result.Number:N0}", "Failure")}")
Console.ReadLine()
'      Output: Success: 123,456

Tuple Visual Basic dan tuple di .NET Framework

Tuple Visual Basic adalah instans dari salah satu jenis generik System.ValueTuple , yang diperkenalkan dalam .NET Framework 4.7. .NET Framework juga mencakup satu set kelas System.Tuple generik. Namun, kelas-kelas ini berbeda dari tuple Visual Basic dan jenis generik System.ValueTuple dalam sejumlah cara:

  • Elemen kelas Tuple adalah properti bernama Item1, Item2, dan sebagainya. Dalam tuple Visual Basic dan jenis ValueTuple, elemen tuple adalah bidang.

  • Anda tidak dapat menetapkan nama yang bermakna ke elemen instans Tuple atau instans ValueTuple. Visual Basic memungkinkan Anda menetapkan nama yang mengomunikasikan arti bidang.

  • Properti instans Tuple bersifat baca-saja; tuple tidak dapat diubah. Dalam tuple Visual Basic dan jenis ValueTuple, bidang tuple bersifat baca-tulis; tuple dapat diubah.

  • Jenis Tuple generik adalah jenis referensi. Menggunakan jenis Tuple ini berarti mengalokasikan objek. Pada jalur panas, ini dapat berdampak terukur pada performa aplikasi Anda. Tuple Visual Basic dan jenis ValueTuple adalah jenis nilai.

Metode ekstensi di kelas TupleExtensions memudahkan konversi antara tuple Visual Basic dan objek Tuple .NET. Metode ToTuple mengonversi tuple Visual Basic menjadi objek Tuple .NET, dan metode ToValueTuple mengonversi objek Tuple .NET menjadi tuple Visual Basic.

Contoh berikut membuat tuple, mengonversinya menjadi objek Tuple .NET, dan mengonversinya kembali ke tuple Visual Basic. Contohnya kemudian membandingkan tuple ini dengan yang asli untuk memastikan bahwa tupel ini sama.

Dim cityInfo = (name:="New York", area:=468.5, population:=8_550_405)
Console.WriteLine($"{cityInfo}, type {cityInfo.GetType().Name}")

' Convert the Visual Basic tuple to a .NET tuple.
Dim cityInfoT = TupleExtensions.ToTuple(cityInfo)
Console.WriteLine($"{cityInfoT}, type {cityInfoT.GetType().Name}")

' Convert the .NET tuple back to a Visual Basic tuple and ensure they are the same.
Dim cityInfo2 = TupleExtensions.ToValueTuple(cityInfoT)
Console.WriteLine($"{cityInfo2}, type {cityInfo2.GetType().Name}")
Console.WriteLine($"{NameOf(cityInfo)} = {NameOf(cityInfo2)}: {cityInfo.Equals(cityInfo2)}")

' The example displays the following output:
'       (New York, 468.5, 8550405), type ValueTuple`3
'       (New York, 468.5, 8550405), type Tuple`3
'       (New York, 468.5, 8550405), type ValueTuple`3
'       cityInfo = cityInfo2 :  True

Lihat juga