switch dan switch expression

switch klasik, bentuk ekspresi modern, dan pola relasional.

Daftar isi

Percabangan dengan banyak pilihan sering kali lebih jelas ditulis dengan switch daripada rangkaian if yang panjang. Topik ini membahas switch klasik, bentuk modern berupa switch expression, serta pola relasional yang memperluas penggunaannya ke pembandingan rentang nilai. Setiap bentuk disertai program yang dijalankan langsung, sehingga perbedaannya terlihat pada kode dan keluarannya.

Switch klasik#

Pernyataan switch mengevaluasi ekspresi (expression), yaitu konstruksi kode yang menghasilkan sebuah nilai, kemudian mencocokkan hasilnya dengan label case satu per satu. Blok yang labelnya cocok dieksekusi, dan default menjadi tujuan apabila tidak ada label yang cocok. Setiap blok case yang memuat pernyataan wajib diakhiri break agar eksekusi keluar dari switch. Beberapa label juga boleh bertumpuk tanpa isi untuk membentuk satu kelompok, sebagaimana pasangan case "Sabtu": case "Minggu": pada program berikut.

csharp Program.cs
// Program klasifikasi hari dengan switch klasik dan switch expression
string hari = "Sabtu";
string jenisHari;

switch (hari)
{
    case "Sabtu":
    case "Minggu":
        jenisHari = "akhir pekan";
        break;
    default:
        jenisHari = "hari kerja";
        break;
}
Console.WriteLine($"{hari} tergolong {jenisHari}");

// switch expression: hasil percabangan ditampung langsung ke variabel
string kategori = hari switch
{
    "Sabtu" or "Minggu" => "akhir pekan",
    _ => "hari kerja"
};
Console.WriteLine($"Kategori: {kategori}");
text Keluaran
Sabtu tergolong akhir pekan
Kategori: akhir pekan

Program tersebut mengklasifikasikan satu nilai dua kali, pertama dengan switch klasik dan kemudian dengan switch expression. Kedua bentuk menghasilkan kategori yang sama, tetapi penulisannya berbeda. Untuk menjalankannya dari folder topik, gunakan perintah berikut.

bash
# 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.cs
text Keluaran
Sabtu tergolong akhir pekan
Kategori: akhir pekan

Blok case yang memuat pernyataan tidak boleh mengalir langsung ke case berikutnya tanpa pernyataan lompat. Apabila break ditinggalkan, kompilator melaporkan error CS0163.

csharp Contoh: case tanpa break yang ditolak kompilator
// tidak-dijalankan
// Contoh: case yang bermuatan pernyataan tanpa break menghasilkan error CS0163
int bulan = 1;

switch (bulan)
{
    case 1:
        Console.WriteLine("Januari");
    case 2:
        Console.WriteLine("Februari");
        break;
}

Larangan ini menutup perilaku fall through bahasa C, yaitu eksekusi yang terus berlanjut ke label berikutnya tanpa sengaja. Perilaku yang dimaksudkan harus ditulis secara eksplisit, misalnya melalui label yang bertumpuk atau pernyataan goto case. Aturan tersebut menjadikan setiap blok case sebagai unit yang berdiri sendiri sehingga alurnya mudah dilacak.

Tipe yang dicocokkan pada contoh adalah string, dan perbandingannya bersifat peka huruf besar kecil, sehingga "Sabtu" dan "sabtu" diperlakukan berbeda. Label default bersifat opsional, tetapi kehadirannya menjamin bahwa seluruh nilai yang mungkin tetap mendapatkan penanganan. Nilai yang dicocokkan juga tidak terbatas pada string maupun int, karena seluruh tipe yang mendukung perbandingan konstanta dapat dipakai sebagai sasaran case.

Switch expression#

Switch expression adalah bentuk modern yang menghasilkan nilai secara langsung, sehingga hasil percabangan dapat ditampung ke variabel dalam satu pernyataan. Setiap baris di dalam kurung kurawal disebut arm, yaitu pola yang diikuti tanda => dan nilai hasilnya. Pola or mencocokkan beberapa nilai sekaligus, sedangkan pola buangan (discard) yang ditulis _ mencocokkan apa pun dan berperan seperti default.

csharp Contoh: switch expression menentukan kategori hari
// Contoh: switch expression yang menentukan kategori hari
string hari = "Rabu";

string kategori = hari switch
{
    "Sabtu" or "Minggu" => "akhir pekan",
    _ => "hari kerja"
};
Console.WriteLine($"{hari}: {kategori}");
text Keluaran
Rabu: hari kerja

Arm dievaluasi berurutan dari atas, dan arm pertama yang polanya cocok menjadi hasilnya. Tidak ada break dalam bentuk ini karena setiap arm hanya menghasilkan satu nilai tanpa badan yang mengalir. Hasil seluruh arm harus dapat disatukan menjadi satu tipe hasil, karena nilai yang dihasilkan hanya satu. Bentuk ekspresi juga memeriksa kelengkapan, misalnya pada tipe bool yang hanya memiliki dua kemungkinan, dan arm yang belum mencakup semua kasus memunculkan warning CS8509 dari kompilator. Hasilnya juga tidak selalu ditampung ke variabel, karena switch expression dapat dipakai di mana pun ekspresi diterima, misalnya sebagai argumen metode atau sebagai nilai kembali. Untuk memilih salah satu dari banyak nilai, switch expression umumnya lebih ringkas daripada switch klasik yang harus menampung hasil lewat variabel sementara.

Pola relasional#

Pola relasional (relational pattern) adalah pola yang membandingkan nilai yang dicocokkan dengan sebuah batas menggunakan operator <, >, <=, dan >=. Seluruh bentuk pola ini menjadi bagian dari pattern matching, yaitu mekanisme C# untuk menguji bentuk dan nilai data di dalam satu konstruksi. Pola ini menjadikan switch expression alat yang tepat untuk klasifikasi rentang, sesuatu yang pada switch klasik harus ditulis sebagai kondisi if di dalam case.

csharp Contoh: pola relasional pada switch expression
// Contoh: pola relasional pada switch expression
int suhu = 31;

string kesimpulan = suhu switch
{
    < 0 => "beku",
    >= 0 and < 20 => "dingin",
    >= 20 and < 30 => "hangat",
    >= 30 and < 40 => "panas",
    _ => "ekstrem"
};
Console.WriteLine($"Suhu {suhu} derajat: {kesimpulan}");
text Keluaran
Suhu 31 derajat: panas

Kombinator and menggabungkan dua batas menjadi satu rentang, sedangkan or menyatukan beberapa kemungkinan dalam satu arm. Setiap pola membandingkan nilai yang sedang dicocokkan sebagai sisi kirinya, sehingga arm >= 30 dibaca sebagai suhu >= 30. Suhu 31 lolos dari tiga arm pertama karena tidak memenuhi batasnya, lalu tertangkap oleh arm >= 30 and < 40. Urutan arm tetap berperan, sehingga rentang yang lebih sempit harus ditulis lebih dahulu, dan arm _ ditempatkan terakhir sebagai penangkap sisa. Pola relasional juga hidup berdampingan dengan pola konstanta dalam satu switch expression, sehingga pencocokan nilai pasti dan pencocokan rentang dapat ditulis dalam satu daftar arm. Apabila klasifikasi hanya melibatkan dua kemungkinan, pernyataan if tetap lebih langsung, sedangkan switch expression unggul ketika tingkatannya tiga atau lebih.

Kesalahan umum#

  • Meninggalkan break pada blok case klasik yang memuat pernyataan. Kompilator menolaknya dengan error CS0163, dan perbaikannya menambahkan break atau mengganti strukturnya dengan switch expression.
  • Menempatkan arm _ sebelum arm lainnya. Arm penangkap apa pun mencocokkan seluruh nilai, sehingga arm yang tertulis di bawahnya tidak pernah tercapai dan pemeriksaan menjadi keliru secara diam-diam.
  • Memakai switch klasik hanya untuk memilih satu nilai ke dalam variabel. Bentuk klasik masih sah, tetapi switch expression menyatakan maksud yang sama tanpa break dan tanpa variabel sementara.

Ringkasan#

  • switch klasik mencocokkan satu ekspresi dengan label case, menuntut break pada setiap blok, dan menyediakan default sebagai pilihan terakhir.
  • switch expression menghasilkan nilai langsung melalui arm yang dievaluasi berurutan, dengan pola or untuk pengelompokan dan _ sebagai penangkap sisa.
  • Pola relasional dengan operator pembanding dan kombinator and serta or memperluas switch expression untuk klasifikasi rentang nilai.

Referensi#