Foto oleh RealToughCandy.com via Pexels

Penyeleksian kondisi dan perulangan adalah dua konstruksi kontrol alur paling dasar dalam pemrograman, memungkinkan program membuat keputusan berdasarkan kondisi tertentu dan mengulang eksekusi kode tanpa harus menulis baris yang sama berkali-kali secara manual.

C# menyediakan beberapa bentuk penyeleksian kondisi seperti if-else dan switch, serta beberapa bentuk perulangan seperti for, while, do-while, dan foreach, masing-masing memiliki kasus penggunaan yang paling sesuai dengan karakteristiknya sendiri.

Artikel ini membahas kapan masing-masing konstruksi ini paling tepat dipakai, termasuk switch expression modern yang lebih ringkas dibanding switch statement tradisional, serta perbedaan penting antara for dan foreach yang sering membingungkan pemula.

If-Else untuk Keputusan Bercabang

If-else berurutan mengevaluasi kondisi dari atas ke bawah

int nilai = 75; if (nilai >= 90) Console.WriteLine("A"); else if (nilai >= 75) Console.WriteLine("B"); else if (nilai >= 60) Console.WriteLine("C"); else Console.WriteLine("D"); -- Expected output: B
Struktur if-else-if dievaluasi secara berurutan dari atas, dan begitu satu kondisi terpenuhi, blok kode yang sesuai dijalankan dan sisa kondisi di bawahnya diabaikan sepenuhnya. Urutan penulisan kondisi menjadi penting terutama ketika rentang nilai saling tumpang tindih seperti pada contoh penentuan nilai huruf ini.

Switch Expression sebagai Alternatif Modern

Switch expression lebih ringkas dibanding if-else berantai

string kategori = nilai switch { >= 90 => "A", >= 75 => "B", >= 60 => "C", _ => "D" }; -- Expected: kategori berisi "B" untuk nilai = 75
Switch expression yang diperkenalkan pada C# 8 memungkinkan penulisan logika kondisional yang setara dengan if-else berantai namun dalam bentuk ekspresi yang bisa langsung menghasilkan nilai, lebih ringkas dan sering dianggap lebih mudah dibaca untuk kasus pemetaan nilai ke kategori seperti ini.

For Loop untuk Perulangan dengan Jumlah Pasti

For loop cocok saat jumlah iterasi sudah diketahui

for (int i = 0; i < 5; i++) { Console.WriteLine($"Iterasi ke-{i}"); } -- Expected: mencetak Iterasi ke-0 sampai Iterasi ke-4, -- total 5 kali perulangan
For loop paling cocok dipakai ketika jumlah iterasi sudah diketahui atau bisa dihitung sejak awal, seperti mengulang sebanyak n kali atau mengakses elemen array berdasarkan indeks tertentu, karena strukturnya secara eksplisit mendefinisikan kondisi awal, kondisi berhenti, dan langkah peningkatan dalam satu baris.

Foreach untuk Iterasi Koleksi

Foreach menyederhanakan iterasi tanpa indeks eksplisit

List<string> buah = new List<string> { "Apel", "Jeruk", "Mangga" }; foreach (string item in buah) { Console.WriteLine(item); } -- Expected: mencetak ketiga nama buah satu per satu, -- tanpa perlu mengelola indeks secara manual
Foreach dirancang khusus untuk mengiterasi setiap elemen dalam koleksi seperti array atau List tanpa perlu mengelola variabel indeks secara manual, membuat kode lebih ringkas dan mengurangi risiko kesalahan off-by-one yang umum terjadi pada for loop biasa, meski foreach tidak mengizinkan mengubah koleksi yang sedang diiterasi secara langsung.

Perbedaan Perilaku Switch Statement dan Switch Expression

Switch expression menggantikan switch-case tradisional yang panjang

int kodeStatus = 2; // Switch expression (C# 8+), lebih ringkas string keterangan = kodeStatus switch { 1 => "Pending", 2 => "Diproses", 3 => "Selesai", _ => "Tidak Diketahui" }; Console.WriteLine(keterangan); // Output: Diproses

Selain switch statement tradisional yang menggunakan kata kunci case dan break pada setiap cabang, C# 8.0 memperkenalkan switch expression yang memungkinkan penulisan logika percabangan menjadi lebih ringkas karena langsung mengembalikan nilai tanpa perlu variabel sementara dan tanpa risiko lupa menuliskan break yang menyebabkan fall-through ke case berikutnya. Tanda garis bawah (_) pada contoh di atas berperan sebagai discard pattern yang menangkap semua nilai yang tidak cocok dengan case manapun, setara dengan default pada switch statement biasa.

Switch expression juga mendukung pattern matching yang lebih kaya dibanding switch statement lama, misalnya mencocokkan tipe data, rentang nilai menggunakan relational pattern (seperti >= 80), atau kombinasi kondisi menggunakan kata kunci and dan or, sehingga logika yang sebelumnya membutuhkan banyak blok if-else bertingkat dapat ditulis dalam satu ekspresi yang lebih mudah dibaca.

Satu aturan penting pada switch expression adalah compiler akan memberikan warning atau error jika tidak semua kemungkinan nilai tertangani dan tidak ada case default (_), karena switch expression wajib menghasilkan nilai untuk setiap kemungkinan input yang mungkin terjadi, berbeda dengan switch statement yang memperbolehkan tidak adanya default case tanpa peringatan.

Perbandingan For, Foreach, While, dan Do-While Serta Break/Continue

continue melewati iterasi, break menghentikan loop sepenuhnya

int[] nilaiUjian = { 70, 85, 40, 90, 60 }; int lulus = 0; foreach (int nilai in nilaiUjian) { if (nilai < 60) continue; // lewati nilai di bawah 60 lulus++; if (lulus == 3) break; // berhenti setelah 3 kelulusan ditemukan } Console.WriteLine(lulus); // Output: 3

C# menyediakan empat bentuk perulangan utama: for yang cocok dipakai ketika jumlah iterasi sudah diketahui pasti sejak awal karena menyatukan inisialisasi, kondisi, dan increment dalam satu baris; foreach yang dirancang khusus untuk mengiterasi koleksi yang mengimplementasikan IEnumerable tanpa perlu mengelola index secara manual; while yang mengevaluasi kondisi sebelum setiap iterasi dijalankan; dan do-while yang menjamin blok kode dijalankan minimal satu kali karena kondisi baru dievaluasi setelah iterasi pertama selesai.

Kata kunci continue dan break memberi kontrol tambahan di dalam loop manapun. Continue akan melompat langsung ke evaluasi kondisi berikutnya tanpa menjalankan sisa kode dalam iterasi saat itu, seperti terlihat pada contoh di atas yang melewati nilai ujian di bawah 60 tanpa menambah variabel lulus. Break sebaliknya akan menghentikan loop sepenuhnya dan melanjutkan eksekusi ke baris kode setelah blok loop berakhir, tanpa memperdulikan apakah kondisi loop masih terpenuhi atau tidak.

Pemilihan jenis loop yang tepat berpengaruh pada keterbacaan kode; foreach umumnya lebih disukai saat bekerja dengan koleksi karena lebih ringkas dan tidak rawan kesalahan index seperti off-by-one error yang sering terjadi pada for. Namun, for tetap diperlukan ketika index elemen dibutuhkan secara eksplisit di dalam logika, misalnya untuk membandingkan elemen saat ini dengan elemen sebelumnya dalam array yang sama. Perlu diperhatikan pula bahwa memodifikasi isi koleksi secara langsung di dalam loop foreach, seperti menambah atau menghapus elemen, akan menimbulkan InvalidOperationException karena foreach bergantung pada enumerator yang menjadi tidak valid begitu koleksi sumbernya berubah di tengah iterasi.

Operator Ternary dan Null-Coalescing Assignment (??=)

int nilai = 75; string keterangan = nilai >= 70 ? "Lulus" : "Tidak Lulus"; string? namaUser = null; namaUser ??= "Guest"; Console.WriteLine(keterangan); Console.WriteLine(namaUser); // Output: // Lulus // Guest

Operator ternary (kondisi ? nilaiJikaBenar : nilaiJikaSalah) adalah bentuk ringkas dari struktur if-else yang mengembalikan satu nilai langsung dalam satu baris ekspresi, cocok untuk kondisi sederhana seperti menentukan status lulus atau tidak berdasarkan satu syarat, tanpa perlu menulis blok if lengkap dengan kurung kurawal hanya untuk memberi nilai pada satu variabel saja, sehingga kode terasa lebih padat dibaca sekilas. Namun untuk kondisi bertingkat atau logika yang lebih rumit, ternary yang ditumpuk bersarang justru membuat kode sulit dipahami dan sebaiknya digantikan dengan if-else biasa atau switch expression.

Operator ??= atau null-coalescing assignment memberi nilai pada variabel hanya jika variabel tersebut saat ini bernilai null, dan tidak melakukan apa-apa jika variabel sudah memiliki nilai sebelumnya. Pola ini sering dipakai untuk memberi nilai default pada parameter opsional, field konfigurasi, atau hasil pembacaan dari sumber eksternal yang mungkin belum diisi, menggantikan pengecekan panjang seperti if (namaUser == null) { namaUser = "Guest"; } menjadi satu baris yang lebih ringkas dan tetap jelas maksudnya.

Kesalahan Umum yang Sering Terjadi

Mengubah Koleksi Saat Sedang Diiterasi dengan Foreach

Menambah atau menghapus elemen dari List yang sedang diiterasi dengan foreach akan menyebabkan InvalidOperationException karena foreach tidak mengizinkan modifikasi koleksi di tengah iterasi, berbeda dengan for loop yang masih memungkinkan hal ini meski tetap berisiko.

Salah Urutan Kondisi pada If-Else Berantai

Menulis kondisi rentang yang lebih kecil terlebih dahulu pada if-else berantai bisa membuat kondisi yang lebih besar tidak pernah tercapai, karena kondisi pertama yang cocok akan langsung dieksekusi tanpa memeriksa sisanya.

Membuat Infinite Loop dengan While yang Lupa Diperbarui

While loop yang kondisinya bergantung pada variabel yang lupa diperbarui di dalam blok loop akan berjalan selamanya, membuat program hang dan harus dihentikan paksa.

Kapan Pendekatan Ini Tidak Cocok Dipakai

If-else lebih fleksibel untuk kondisi kompleks yang melibatkan banyak variabel berbeda, sementara switch lebih cocok untuk membandingkan satu variabel terhadap banyak kemungkinan nilai diskrit, dengan keterbacaan yang lebih baik ketika jumlah kemungkinannya banyak.

For loop memberikan kontrol penuh atas indeks dan kondisi berhenti, berguna ketika logika loop membutuhkan akses ke posisi elemen, sementara foreach lebih aman dan ringkas namun kehilangan akses langsung ke indeks kecuali ditambahkan penghitung manual terpisah.

Ringkasan

Pemilihan konstruksi kontrol alur yang tepat, baik if-else, switch, for, while, maupun foreach, bergantung pada karakteristik masalah yang dihadapi. Pahami kapan masing-masing paling sesuai dipakai agar kode yang ditulis tidak hanya benar secara fungsional, tetapi juga mudah dibaca dan dipelihara oleh developer lain.