VB.NET dan C# adalah dua bahasa berbeda yang dikompilasi ke representasi menengah yang sama pada .NET. Topik ini membaca contoh kode C# yang pendek, menemukan perbedaan sintaks yang paling menonjol dari sudut pandang VB.NET, lalu menerjemahkannya menjadi program VB.NET yang dijalankan. Hasil yang diperoleh adalah kemampuan membaca contoh C# dari dokumentasi maupun artikel daring dan memindahkannya ke VB.NET dengan pemahaman mekanismenya.
Satu runtime, dua bahasa#
Kompiler VB.NET dan kompiler C# sama-sama menghasilkan Intermediate Language (IL), yaitu representasi menengah yang dijalankan oleh runtime .NET yang sama. Keduanya juga mengakses pustaka kelas .NET yang identik, dan Common Type System menetapkan tipe yang digunakan bersama oleh seluruh bahasa .NET. Akibat langsungnya, kelas yang ditulis dalam C# dapat digunakan dari proyek VB.NET tanpa konversi apa pun, dan sebaliknya.
Posisi keduanya berbeda dalam ekosistem. Fitur baru .NET biasanya tampil di C# lebih dahulu, sedangkan VB.NET tetap dipelihara dengan penambahan yang lebih jarang. Penggunaan praktisnya juga terbagi, yaitu aplikasi internal perusahaan masih banyak ditulis dengan VB, sementara proyek open source dan contoh daring didominasi C#. Karena sebagian besar contoh pada dokumentasi pustaka pihak ketiga, forum, dan tanya jawab daring ditulis dalam C#, kemampuan membaca C# memperluas akses terhadap pengetahuan teknis yang sudah terkumpul di sumber-sumber itu.
Untungnya, kedua bahasa berbagi konsep yang sama, mulai dari kelas, properti, exception, hingga generics, sehingga perbedaan terbesarnya berada di tata bahasa permukaan. Tabel berikut memetakan bentuk yang paling sering ditemui saat membaca contoh C#.
Pemetaan sintaks utama#
| Aspek | C# | VB.NET |
|---|---|---|
| Impor namespace | using System; | Imports System |
| Kelas | class RekapNilai { ... } | Class RekapNilai ... End Class |
| Metode | double RataRata() { ... } | Function RataRata() As Double ... End Function |
| Prosedur tanpa hasil | void Cetak() { ... } | Sub Cetak() ... End Sub |
| Akhir pernyataan | titik koma ; | akhir baris |
| Blok kode | kurung kurawal { } | kata kunci End |
| Komentar | // komentar | ' komentar |
| Huruf besar-kecil | sensitif | tidak sensitif |
| Deklarasi variabel | var nilai = new List<int>(); | Dim nilai As New List(Of Integer) |
| Interpolasi string | $"Rata-rata: {x}" | $"Rata-rata: {x}" |
| Properti otomatis | public int Umur { get; set; } | Public Property Umur As Integer |
| Nilai yang mungkin kosong | int? stok | Dim stok As Integer? |
| Pemeriksaan kosong | x == null atau x is null | x Is Nothing |
| Lambda | n => n * 2 | Function(n) n * 2 |
Dua baris pada tabel menonjol karena bentuknya sama persis, yaitu interpolasi string dengan awalan $ dan tanda kurung kurawal. Kedua bahasa menggunakan mekanisme kompilator yang sejenis untuk fitur itu. Baris int? dan Integer? sama-sama menyatakan tipe nilai yang boleh kosong (nullable), sedangkan anotasi string? pada C# adalah bagian dari fitur nullable reference type yang tidak memiliki padanan penulisan di VB.NET, sehingga cukup diterjemahkan menjadi String biasa.
Cara memanfaatkan tabel ini adalah membaca baris demi baris dari contoh C# yang sedang diterjemahkan, lalu mencari aspeknya pada kolom C# sebelum menuliskan bentuk VB.NET-nya. Baris-baris yang tidak ada padanannya satu banding satu, misalnya => untuk lambda, diterjemahkan sesuai konsepnya dan bukan sesuai bentuk penulisannya. Pemeriksaan tabel biasanya cukup untuk contoh pendek, sedangkan contoh yang panjang sebaiknya diterjemahkan satu kelas pada satu waktu agar kesalahannya mudah dilacak.
Membaca contoh C##
Contoh berikut adalah program C# lengkap yang akan diterjemahkan. Program ini menghitung rata-rata sekumpulan nilai lalu menetapkan predikatnya, dan keduanya dikerjakan oleh kelas RekapNilai.
// tidak-dijalankan
using System;
using System.Collections.Generic;
namespace Statistik
{
public class RekapNilai
{
public string? Predikat(double rataRata)
{
if (rataRata >= 75.0)
{
return "Baik";
}
return "Perlu bimbingan";
}
public double RataRata(List<int> nilai)
{
int total = 0;
foreach (int n in nilai)
{
total += n;
}
if (nilai.Count == 0)
{
return 0.0;
}
return total / (double)nilai.Count;
}
}
public class Program
{
public static void Main()
{
var rekap = new RekapNilai();
var nilai = new List<int> { 70, 80, 90 };
Console.WriteLine($"Rata-rata: {rekap.RataRata(nilai)}");
Console.WriteLine($"Predikat: {rekap.Predikat(rekap.RataRata(nilai))}");
}
}
}Beberapa hal terbaca langsung setelah tabel pemetaan. Kata using di kepala berkas adalah Imports, kata namespace beserta kurung kurawalnya adalah Namespace ... End Namespace, dan foreach adalah For Each. Tipe ditulis sebelum nama di C#, misalnya double rataRata pada parameter, lalu berpindah menjadi rataRata As Double di VB. Kata var menyembunyikan tipe karena kompiler C# menyimpulkannya dari sisi kanan, sehingga pasangannya adalah Dim dengan tipe yang dituliskan eksplisit. Interpolasi $"..." dan pemanggilan Console.WriteLine tidak perlu diubah sama sekali karena bentuknya sudah identik.
Menerjemahkan ke VB.NET#
Terjemahan lengkapnya adalah program berikut yang dijalankan di sandbox.
Imports System.Collections.Generic
Namespace Statistik
Public Class RekapNilai
Public Function Predikat(rataRata As Double) As String
If rataRata >= 75.0 Then
Return "Baik"
End If
Return "Perlu bimbingan"
End Function
Public Function RataRata(nilai As List(Of Integer)) As Double
Dim total As Integer = 0
For Each n As Integer In nilai
total += n
Next
If nilai.Count = 0 Then
Return 0.0
End If
Return total / CDbl(nilai.Count)
End Function
End Class
Public Class Program
Public Shared Sub Main()
Dim rekap As New RekapNilai()
Dim nilai As New List(Of Integer) From {70, 80, 90}
Console.WriteLine($"Rata-rata: {rekap.RataRata(nilai)}")
Console.WriteLine($"Predikat: {rekap.Predikat(rekap.RataRata(nilai))}")
End Sub
End Class
End NamespaceRata-rata: 80
Predikat: BaikKeputusan penerjemahannya dapat ditelusuri satu per satu sebagai berikut.
using System.Collections.Generic;menjadiImports System.Collections.Generictanpa titik koma.namespace Statistik { ... }menjadi blokNamespace Statistik ... End Namespace, danpublicmenjadiPublic.string? Predikat(double rataRata)menjadiFunction Predikat(rataRata As Double) As String, dengan tipe hasil berpindah ke klausaAsdi akhir.foreach (int n in nilai)menjadiFor Each n As Integer In nilai, dan penambahannya tetaptotal += n.- Cast eksplisit
(double)nilai.CountmenjadiCDbl(nilai.Count), karena fungsi konversi memainkan peran yang sama. var rekap = new RekapNilai();menjadiDim rekap As New RekapNilai(), dan inisialisasi koleksi{ 70, 80, 90 }menggunakan kata kunciFrom.public static void Main()menjadiPublic Shared Sub Main(), karenastaticdipadankan denganShared.
Keluaran dari kedua bahasa itu identik karena keduanya menghitung dengan logika yang sama, yaitu rata-rata 80 dan predikat “Baik” dari ambang 75. Pemeriksaan semacam ini sebaiknya diulang untuk setiap terjemahan, karena kesamaan keluaran pada data contoh bukan jaminan kesamaan perilaku pada semua data.
Kesalahan umum#
Kesalahan pertama adalah menempelkan kode C# langsung ke berkas .vb berharap kompiler menyesuaikannya. Hasilnya deretan error sintaks karena titik koma, kurung kurawal, dan tanda ? bukan bagian tata bahasa VB.NET. Terjemahkan dahulu dengan tabel pemetaan, lalu periksa semantikanya.
Kesalahan kedua adalah mengabaikan sensitivitas huruf besar-kecil. Dua nama total dan Total pada C# adalah dua variabel berbeda, sedangkan VB.NET menganggapnya sama. Saat membaca C#, perbedaan kapitalisasi harus dicatat sebagai pembeda nama, dan saat menulis VB.NET, huruf besar-kecil tidak boleh dijadikan cara membedakan dua nama.
Kesalahan ketiga adalah menerjemahkan operator dan pemeriksaan kosong secara kata per kata. Pembagian int pada C# memotong hasilnya, pemeriksaan == null menjadi Is Nothing, dan string? tidak memiliki padanan penulisan. Kesalahan semacam ini lolos dari pemeriksaan sintaks karena bentuknya sah, tetapi programnya berperilaku berbeda dari aslinya.
Ringkasan#
- VB.NET dan C# menghasilkan IL yang sama, berbagi runtime dan pustaka kelas, sehingga kelas dari keduanya saling digunakan tanpa konversi.
- Perbedaannya menumpuk di permukaan, yaitu akhir baris melawan titik koma, blok kata kunci melawan kurung kurawal, dan sensitivitas huruf besar-kecil.
- Terjemahan yang andal memeriksa semantika operator dan pemeriksaan kosong, misalnya pembagian
intpada C# danIs Nothingpada VB.NET.
Referensi#
- Visual Basic language reference — Microsoft Learn — Rujukan lengkap sintaks VB.NET untuk memeriksa padanan kata kunci.
- C# language reference — Microsoft Learn — Rujukan sintaks C# yang digunakan saat membaca contoh.
- Common Type System — Microsoft Learn — Sistem tipe bersama yang digunakan seluruh bahasa .NET.