Bagikan melalui


Prosedur pemecahan masalah (Visual Basic)

Halaman ini mencantumkan beberapa masalah umum yang dapat terjadi saat bekerja dengan prosedur.

Mengembalikan jenis array dari prosedur fungsi

Function Jika prosedur mengembalikan jenis data array, Anda tidak dapat menggunakan Function nama untuk menyimpan nilai dalam elemen array. Jika Anda mencoba melakukan ini, pengkompilasi menafsirkannya sebagai panggilan ke Function. Contoh berikut menghasilkan kesalahan kompilator:

Function AllOnes(n As Integer) As Integer()
   For i As Integer = 1 To n - 1  
      ' The following statement generates a COMPILER ERROR.  
      AllOnes(i) = 1  
   Next  

   ' The following statement generates a COMPILER ERROR.  
   Return AllOnes()  
End Function

Pernyataan AllOnes(i) = 1 menghasilkan kesalahan kompilator karena tampaknya memanggil AllOnes dengan argumen jenis data yang salah (skalar Integer alih-alih Integer array). Pernyataan Return AllOnes() menghasilkan kesalahan kompilator karena tampaknya memanggil AllOnes tanpa argumen.

Pendekatan yang benar: Agar dapat memodifikasi elemen array yang akan dikembalikan, tentukan array internal sebagai variabel lokal. Contoh berikut mengkompilasi tanpa kesalahan:

Function AllOnes(n As Integer) As Integer()
    Dim iArray(n - 1) As Integer
    For i = 0 To n - 1
        iArray(i) = 1
    Next
    Return iArray
End Function

Argumen tidak dimodifikasi oleh panggilan prosedur

Jika Anda ingin mengizinkan prosedur untuk mengubah elemen pemrograman yang mendasar argumen dalam kode panggilan, Anda harus meneruskannya dengan referensi. Tetapi prosedur dapat mengakses elemen argumen jenis referensi bahkan jika Anda meneruskannya berdasarkan nilai.

  • Variabel yang mendasar. Untuk memungkinkan prosedur mengganti nilai elemen variabel yang mendasar itu sendiri, prosedur harus mendeklarasikan parameter ByRef. Selain itu, kode panggilan tidak boleh mengapit argumen dalam tanda kurung, karena itu akan mengambil alih ByRef mekanisme passing.

  • Elemen jenis referensi. Jika Anda mendeklarasikan parameter ByVal, prosedur tidak dapat mengubah elemen variabel yang mendasar itu sendiri. Namun, jika argumen adalah jenis referensi, prosedur dapat memodifikasi anggota objek yang ditujukannya, meskipun tidak dapat menggantikan nilai variabel. Misalnya, jika argumen adalah variabel array, prosedur tidak dapat menetapkan array baru ke dalamnya, tetapi dapat mengubah satu atau beberapa elemennya. Elemen yang diubah tercermin dalam variabel array yang mendasar dalam kode panggilan.

Contoh berikut mendefinisikan dua prosedur yang mengambil variabel array berdasarkan nilai dan beroperasi pada elemennya. Prosedur increase hanya menambahkan satu ke setiap elemen. Prosedur replace menetapkan array baru ke parameter a() lalu menambahkannya ke setiap elemen. Namun, penetapan ulang tidak memengaruhi variabel array yang mendasar dalam kode panggilan karena a() dinyatakan ByVal.

Public Sub increase(ByVal a() As Long)
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub
Public Sub replace(ByVal a() As Long)
    Dim k() As Long = {100, 200, 300}
    a = k
    For j As Integer = 0 To UBound(a)
        a(j) = a(j) + 1
    Next j
End Sub

Contoh berikut melakukan panggilan ke increase dan replace:

Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " & 
    CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))

Panggilan pertama MsgBox menampilkan "Setelah peningkatan(n): 11, 21, 31, 41". Karena n merupakan jenis referensi, increase dapat mengubah anggotanya, meskipun diteruskan ByVal.

Panggilan kedua MsgBox menampilkan "Setelah ganti(n): 11, 21, 31, 41". Karena n diteruskan ByVal, replace tidak dapat mengubah variabel n dengan menetapkan array baru ke dalamnya. Saat replace membuat instans k array baru dan menetapkannya ke variabel alokal , instans kehilangan referensi untuk n diteruskan oleh kode panggilan. Ketika menaikkan anggota a, hanya array k lokal yang terpengaruh.

Pendekatan yang benar: Untuk dapat memodifikasi elemen variabel yang mendasar itu sendiri, lewati dengan referensi. Contoh berikut menunjukkan perubahan dalam deklarasi replace yang memungkinkannya mengganti satu array dengan array lainnya dalam kode panggilan:

Public Sub replace(ByRef a() As Long)

Tidak dapat menentukan kelebihan beban

Jika Anda ingin menentukan versi prosedur yang kelebihan beban, Anda harus menggunakan nama yang sama tetapi tanda tangan yang berbeda. Jika kompilator tidak dapat membedakan deklarasi Anda dari kelebihan beban dengan tanda tangan yang sama, itu menghasilkan kesalahan.

Tanda tangan prosedur ditentukan oleh nama prosedur dan daftar parameter. Setiap kelebihan beban harus memiliki nama yang sama dengan semua kelebihan beban lainnya tetapi harus berbeda dari semuanya di setidaknya salah satu komponen lain dari tanda tangan. Untuk informasi selengkapnya, lihat Kelebihan Muatan Prosedur.

Item berikut, meskipun berkaitan dengan daftar parameter, bukan komponen tanda tangan prosedur:

  • Kata kunci pengubah prosedur, seperti Public, , Shareddan Static.
  • Nama parameter.
  • Kata kunci pengubah parameter, seperti ByRef dan Optional.
  • Jenis data nilai yang dikembalikan (kecuali untuk operator konversi).

Anda tidak dapat membebani prosedur dengan hanya memvariasikan satu atau beberapa item sebelumnya.

Pendekatan yang benar: Agar dapat menentukan kelebihan beban prosedur, Anda harus memvariasi tanda tangan. Karena Anda harus menggunakan nama yang sama, Anda harus memvariasikan jumlah, urutan, atau jenis data parameter. Dalam prosedur generik, Anda dapat memvariasi jumlah parameter jenis. Di operator konversi (Operator CType), Anda dapat memvariasi jenis pengembalian.

Resolusi kelebihan beban dengan argumen Opsional dan ParamArray

Jika Anda membebani prosedur dengan satu atau beberapa parameter Opsional atau parameter ParamArray , Anda harus menghindari duplikat salah satu kelebihan beban implisit. Untuk informasi, lihat Pertimbangan dalam Prosedur Kelebihan Beban.

Memanggil versi prosedur yang kelebihan beban yang salah

Jika prosedur memiliki beberapa versi yang kelebihan beban, Anda harus terbiasa dengan semua daftar parameternya dan memahami bagaimana Visual Basic menyelesaikan panggilan di antara kelebihan beban. Jika tidak, Anda dapat memanggil kelebihan beban selain yang dimaksudkan.

Ketika Anda telah menentukan kelebihan beban mana yang ingin Anda panggil, berhati-hatilah untuk mengamati aturan berikut:

  • Berikan jumlah argumen yang benar, dan dalam urutan yang benar.
  • Idealnya, argumen Anda harus memiliki jenis data yang sama persis dengan parameter yang sesuai. Bagaimanapun, jenis data dari setiap argumen harus melebar ke parameter yang sesuai. Ini benar bahkan dengan Pernyataan Ketat Opsi diatur ke Off. Jika kelebihan beban memerlukan konversi yang menyempit dari daftar argumen Anda, kelebihan beban tersebut tidak memenuhi syarat untuk dipanggil.
  • Jika Anda menyediakan argumen yang memerlukan pellebaran, buat jenis datanya sedekat mungkin dengan jenis data parameter yang sesuai. Jika dua atau lebih kelebihan beban menerima jenis data argumen Anda, pengkompilasi menyelesaikan panggilan Anda ke kelebihan beban yang memanggil untuk jumlah pelebaran paling sedikit.

Anda dapat mengurangi kemungkinan ketidakcocokan jenis data dengan menggunakan kata kunci konversi Fungsi CType saat menyiapkan argumen Anda.

Kegagalan resolusi kelebihan beban

Ketika Anda memanggil prosedur yang kelebihan beban, pengkompilasi mencoba menghilangkan semua kecuali salah satu kelebihan beban. Jika berhasil, itu menyelesaikan panggilan ke kelebihan beban tersebut. Jika menghilangkan semua kelebihan beban, atau jika tidak dapat mengurangi kelebihan beban yang memenuhi syarat ke satu kandidat, itu menghasilkan kesalahan.

Contoh berikut mengilustrasikan proses resolusi kelebihan beban:

Overloads Sub z(ByVal x As Byte, ByVal y As Double)
End Sub
Overloads Sub z(ByVal x As Short, ByVal y As Single)
End Sub
Overloads Sub z(ByVal x As Integer, ByVal y As Single)
End Sub
Dim r, s As Short
Call z(r, s)
Dim p As Byte, q As Short
' The following statement causes an overload resolution error.
Call z(p, q)

Dalam panggilan pertama, pengkompilasi menghilangkan kelebihan beban pertama karena jenis argumen pertama (Short) menyempit ke jenis parameter yang sesuai (Byte). Kemudian menghilangkan kelebihan beban ketiga karena setiap jenis argumen dalam kelebihan beban kedua (Short dan Single) melebar ke jenis yang sesuai dalam kelebihan beban ketiga (Integer dan Single). Kelebihan beban kedua membutuhkan lebih sedikit pelesiran, sehingga pengkompilasi menggunakannya untuk panggilan.

Pada panggilan kedua, pengkompilasi tidak dapat menghilangkan salah satu kelebihan beban berdasarkan penyempitan. Ini menghilangkan kelebihan beban ketiga karena alasan yang sama seperti pada panggilan pertama, karena dapat memanggil kelebihan beban kedua dengan lebih sedikit pelesiran jenis argumen. Namun, pengkompilasi tidak dapat menyelesaikan antara kelebihan beban pertama dan kedua. Masing-masing memiliki satu jenis parameter yang ditentukan yang melebar ke jenis yang sesuai di yang lain (Byte ke Short, tetapi Single ke Double). Oleh karena itu, pengkompilasi menghasilkan kesalahan resolusi kelebihan beban.

Pendekatan yang benar: Agar dapat memanggil prosedur kelebihan beban tanpa ambiguitas, gunakan Fungsi CType untuk mencocokkan jenis data argumen dengan jenis parameter. Contoh berikut menunjukkan panggilan ke z yang memaksa resolusi ke kelebihan beban kedua.

Call z(CType(p, Short), CType(q, Single))

Resolusi kelebihan beban dengan argumen Opsional dan ParamArray

Jika dua kelebihan beban prosedur memiliki tanda tangan yang identik kecuali bahwa parameter terakhir dinyatakan Opsional dalam satu dan ParamArray di yang lain, pengkompilasi menyelesaikan panggilan ke prosedur tersebut sesuai dengan kecocokan terdekat. Untuk informasi selengkapnya, lihat Resolusi Kelebihan Beban.

Lihat juga