pattern matching adalah mekanisme menguji bentuk dan isi sebuah nilai terhadap pola, lalu memilih cabang yang cocok, dan C# mengeksekusinya lewat ekspresi switch serta operator is. Topik ini memperdalam tiga kelompok pola yang paling sering dipakai, yaitu pola tipe yang mengenali jenis object, pola properti yang menguji isi field atau propertinya, dan pola logika yang menggabungkan beberapa syarat dengan and, or, serta not. Semua contoh dijalankan dengan satu program sehingga urutan dan hasil setiap pola dapat diperiksa dari keluarannya.
Pola tipe#
Pola tipe menguji apakah sebuah nilai bertipe tertentu, sekaligus menyimpannya ke variabel baru apabila cocok. Bentuk paling ringkasnya memakai operator is, seperti isi is string teks, yang bernilai true apabila isi bertipe string dan langsung menyiapkan variabel teks yang sudah bertipe tepat untuk dipakai di dalam pencabangan. Bentuk yang lebih lengkapnya berada di dalam ekspresi switch, dan program berikut memakainya untuk mengklasifikasikan daftar object yang isinya beragam.
// Program demonstrasi pola tipe, pola properti, dan pola logika
object?[] daftarBentuk =
{
new Lingkaran(3.0),
new PersegiPanjang(4.0, 5.0),
new PersegiPanjang(3.0, 3.0),
"teks biasa",
null
};
foreach (object? bentuk in daftarBentuk)
{
Console.WriteLine(Deskripsi(bentuk));
}
int nilai = 85;
string predikat = nilai switch
{
>= 90 => "sangat baik",
>= 80 and < 90 => "baik",
>= 70 and < 80 => "cukup",
_ => "di bawah batas kelulusan"
};
Console.WriteLine($"nilai 85 -> predikat {predikat}");
object isi = "kata kunci";
if (isi is string teks && teks.Length > 3)
{
Console.WriteLine($"teks \"{teks}\" berisi {teks.Length} karakter");
}
string Deskripsi(object? bentuk) => bentuk switch
{
Lingkaran { Radius: > 0 } c => $"lingkaran dengan luas {Math.PI * c.Radius * c.Radius:F2}",
Lingkaran => "lingkaran dengan jari-jari tidak valid",
PersegiPanjang p when p.Panjang == p.Lebar => $"persegi sempurna dengan sisi {p.Panjang}",
PersegiPanjang p => $"persegi panjang {p.Panjang} x {p.Lebar}",
string teks => $"teks sepanjang {teks.Length} karakter",
null => "bentuk kosong",
_ => "bentuk tidak dikenal"
};
record Lingkaran(double Radius);
record PersegiPanjang(double Panjang, double Lebar);lingkaran dengan luas 28.27
persegi panjang 4 x 5
persegi sempurna dengan sisi 3
teks sepanjang 10 karakter
bentuk kosong
nilai 85 -> predikat baik
teks "kata kunci" berisi 10 karakterUntuk menjalankan program tersebut dari folder topik, gunakan perintah berikut.
# aktifkan .NET yang terpasang di sandbox
export DOTNET_ROOT=/home/kal/.dotnet PATH=/home/kal/.dotnet:$PATH DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
# jalankan program contoh dari folder topik
dotnet run --file Program.cslingkaran dengan luas 28.27
persegi panjang 4 x 5
persegi sempurna dengan sisi 3
teks sepanjang 10 karakter
bentuk kosong
nilai 85 -> predikat baik
teks "kata kunci" berisi 10 karakterLima baris pertama keluaran berasal dari ekspresi switch pada metode Deskripsi. Tipe Lingkaran dan PersegiPanjang dideklarasikan sebagai record, yaitu tipe referensi ringkas yang datanya ditentukan lewat parameternya, sehingga pola tipe dapat menangkap object beserta properti posisinya. Cabang pertama yang cocok menjadi satu-satunya yang dieksekusi, sehingga penulisan Lingkaran { Radius: > 0 } sebelum Lingkaran menjamin lingkaran dengan jari-jari tidak valid diperiksa lebih dahulu, dan urutan cabang (arm) menentukan hasil akhirnya.
Pola tipe juga dapat ditulis tanpa deklarasi variabel, sebagaimana cabang Lingkaran kedua pada metode Deskripsi yang hanya memerlukan tipenya dan tidak memakai isinya. Bentuk tanpa variabel membuat maksud cabang lebih jelas karena pembaca langsung melihat bahwa isinya diabaikan, sekaligus menghindari variabel yang tidak terpakai beserta peringatan kompilatornya. Sebaliknya, cabang string teks memang memakai isinya untuk menghitung panjang teks, sehingga deklarasi variabelnya diperlukan dan langsung tersedia di ekspresi kanan cabang tersebut.
Pola properti#
Pola properti menguji isi object yang sudah dikenali tipenya, ditulis dengan kurung kurawal di dalam polanya, misalnya Lingkaran { Radius: > 0 }. Pola ini menangkap object hanya apabila properti Radius memenuhi pola relasional > 0, dan variabel c pada akhirnya memegang object yang sudah lolos pemeriksaan. Pemeriksaan tambahan juga dapat dinyatakan dengan klausa when, seperti pada cabang PersegiPanjang p when p.Panjang == p.Lebar yang membedakan persegi sempurna dari persegi panjang biasa sebelum cabang yang lebih umum menangkapnya.
Properti di dalam pola properti dapat diuji secara bersarang, sehingga pola seperti Peminjaman { Anggota: { Nama: "Budi" } } mampu menelusuri isi object di dalam object tanpa pencabangan manual. Pola relasional <, >, <=, dan >= berlaku untuk tipe yang mendukung pembandingan, sedangkan pola konstanta membandingkan dengan nilai tertentu. Gabungan keduanya menjadikan ekspresi switch mampu menuliskan keputusan berlapis dalam satu daftar cabang yang terbaca dari atas ke bawah.
Pola logika#
Pola logika menggabungkan pola-pola yang sudah ada dengan operator and, or, dan not. Program di atas memakai >= 80 and < 90 untuk menyatakan rentang predikat baik dalam satu cabang, dan bentuk ini menggantikan dua pemeriksaan bersarang menjadi satu pernyataan. Operator not biasanya dipakai untuk menolak pola tertentu, misalnya not null yang cocok untuk semua nilai kecuali kosong, sehingga penanganan nilai kosong dapat diletakkan di cabang tersendiri di belakangnya.
// Contoh: pola logika or pada pemeriksaan teks
string hari = "sabtu";
string jenis = hari switch
{
"sabtu" or "minggu" => "akhir pekan",
not null => "hari kerja",
null => "tidak diketahui"
};
Console.WriteLine($"jenis = {jenis}");jenis = akhir pekanCabang "sabtu" or "minggu" mencocokkan kedua teks tersebut dalam satu baris, sedangkan cabang not null menampung sisa teks yang tidak kosong dan cabang null menjadi penutup. Ekspresi switch menuntut daftar cabangnya lengkap, yaitu tidak ada nilai yang mungkin lolos tanpa cabang, dan kompilator (compiler) memperingatkan dengan warning CS8509 apabila daftar tersebut belum lengkap. Nilai yang lolos dari daftar yang tidak lengkap memicu exception, yaitu object error yang dilempar saat program berjalan, sehingga cabang cadangan _ atau null perlu selalu disediakan.
Kesalahan umum#
- Mengurutkan cabang dari yang umum ke yang spesifik. Cabang pertama yang cocok menang, sehingga pola properti yang memeriksa isi harus mendahului pola tipe polosnya.
- Meninggalkan daftar cabang tanpa penutup. Ekspresi
switchyang belum lengkap menghasilkan warning CS8509, dan nilai yang lolos memicu exception saat program berjalan. - Mengabaikan nilai
nullpada input bertipe referensi. Pola tipe sepertistring tekstidak menangkapnull, sehingga cabang khususnulldiperlukan agar nilainya tertangani dengan jelas.
Ringkasan#
- Pola tipe mengenali jenis nilai dengan
isatau cabangswitchdan sekaligus menyiapkan variabel bertipe tepat, sedangkan pola properti menguji isi field atau properti object yang dimilikinya. - Pola logika
and,or, dannotmenggabungkan syarat menjadi satu cabang, dan klausawhenmenambah pemeriksaan yang tidak terwakili pola. - Urutan cabang menentukan hasil karena cabang pertama yang cocok menang, dan ekspresi
switchmenuntut daftar cabang yang lengkap dengan cabang cadangan_.
Referensi#
- Pattern matching overview — Microsoft Learn — Gambaran resmi pattern matching C# beserta contoh pola tipe, properti, dan relasionalnya.
- Records (C# reference) — Microsoft Learn — Rujukan resmi record yang dipakai sebagai tipe data pada contoh pola.