You are currently viewing Mengatur Alur Eksekusi Dengan Percabangan switch di C#

Mengatur Alur Eksekusi Dengan Percabangan switch di C#

Halo! Selamat datang kembali di “Seri Belajar Dasar Pemrograman Bahasa C#“. Setelah mempelajari bagaimana menggunakan pernyataan if di C#, pada materi kali ini kita akan mempelajari bagaimana mengatur alur eksekusi dengan percabangan switch di C#.

Setelah mempelajari materi ini, Anda akan mendapatkan pemahaman tentang bagaimana cara menggunakan pernyataan switch di C# dan kapan situasi yang tepat untuk menggunakannya dibanding menggunakan pernyataan if.

Pernyataan Switch

Menggunakan pernyataan if – else if untuk mengevaluasi berbagai kemungkinan kondisi membuat baris kode program kita berpotensi untuk susah dibaca. Untuk mengatasi hal ini, C# memiliki alternatif konstruksi percabangan menggunakan pernyataan switch.

Oleh karena itu, pernyataan if – else if seperti pada kode program di bawah ini,

Console.Write("Pilih buah kesukaan Anda (apel/jeruk/pisang): ");
string pilihan = Console.ReadLine().ToLower();

if (pilihan == "apel")
    Console.WriteLine("Anda memilih buah apel");
else if (pilihan == "jeruk")
    Console.WriteLine("Anda memilih buah jeruk");
else if (pilihan == "jeruk")
    Console.WriteLine("Anda memilih buah jeruk");
else
    Console.WriteLine("Anda memilih yang lain");

Bisa diganti dengan pernyataan switch seperti kode program di bawah ini.

Console.Write("Pilih buah kesukaan Anda (apel/jeruk/pisang): ");
string pilihan = Console.ReadLine().ToLower();

switch (pilihan)
{
    case "apel":
        Console.WriteLine("Anda memilih buah apel");
        break;
    case "jeruk":
        Console.WriteLine("Anda memilih buah jeruk");
        break;
    case "pisang":
        Console.WriteLine("Anda memilih buah pisang");
        break;
    default:
        Console.WriteLine("Anda memilih yang lain");
        break;
}

Pada kode program di atas, nilai variabel pilihan akan dievaluasi oleh pernyataan switch. Lalu, pernyataan switch akan mencocokkan nilai variabel tersebut dengan beberapa kemungkinan nilai (biasa disebut dengan “pola”) yang ada pada setiap label case.

Misalnya, jika nilai variabel pilihan adalah “apel”, maka pola label case yang cocok adalah label case "apel". Oleh karena itu, baris kode program atau pernyataan pada label tersebut yang dieksekusi.

Match Expression

Pada sebuah pernyataan switch, ekspresi di dalam tanda kurung setelah kata kunci switch disebut dengan match expression.

switch(match_expression)

Nilai dari match expression ini nantinya akan dicocokkan dengan setiap pola yang ada pada label case. Pada contoh sebelumnya, variabel pilihan merupakan match expression yang digunakan pada pernyataan switch.

Dimulai dari C# 7.0, match expression dapat berupa ekspresi yang menghasilkan nilai dari tipe data apapun selain null.

Switch Section

Sebuah pernyataan switch biasanya terdiri dari satu atau lebih switch section. Setiap switch section sendiri, bisa terdiri dari satu atau lebih label case. Sebuah pernyataan switch bisa memiliki paling banyak satu label default yang bisa diletakkan di switch section manapun.

Contoh kode program di bawah ini mendemonstrasikan sebuah pernyataan switch sederhana yang terdiri dari tiga switch section. Switch section kedua terdiri dari dua label case. Susunan seperti pada switch section kedua, di mana bagian ini terdiri dari lebih dari satu label case, disebut dengan fall through setup.

// Membuat generator angka acak
Random rnd = new Random();

// Menghasilkan angka acak antara 1-4
int caseSwitch = rnd.Next(1,4);

switch (caseSwitch)
{
    // switch section pertama
    case 1:
        Console.WriteLine("Case 1");
        break;

    // switch section kedua
    // fall through setup
    case 2: // label case pertama pada switch section kedua
    case 3: // label case kedua pada switch section kedua
        Console.WriteLine($"Case {caseSwitch}");
        break;

    // switch section ketiga
    default:
        Console.WriteLine($"Case lain di luar 1-3: ({caseSwitch})");
        break;
}

Case Label

Label case pada pernyataan switch berfungsi untuk menentukan sebuah pola yang nantinya akan dibandingkan dengan nilai match expression-nya (variabel caseSwitch pada contoh di atas).

Jika terdapat pola yang cocok pada sebuah label case, maka eksekusi program akan melompat ke label case tersebut.

Default Case

Apabila tidak ada pola pada label case yang cocok dengan nilai match expression-nya, maka eksekusi program akan melompat ke label default.

Kita tidak selalu diharuskan menyediakan label default di dalam sebuah pernyataan switch. Jika di dalam pernyataan switch tidak terdapat label default, maka eksekusi program akan langsung lompat keluar pernyataan switch apabila pola yang cocok dengan nilai match expression-nya tidak bisa ditemukan.

Jump Statement

Pada setiap pernyataan case di atas, perhatikan penggunaan kata kunci break. Jika kita tidak menambahkan kata kunci break, maka kontrol alur eksekusi akan mencoba melanjutkan eksekusi ke label case di bawahnya.

Namun di C#, hal ini akan menyebabkan eror “Control cannot fall through from one case label”. Selain menggunakan jump statement goto case, pernyataan switch hanya mengeksekusi satu switch section saja. Artinya, setelah satu switch section selesai dieksekusi, eksekusi program tidak bisa dilanjutkan ke switch section berikutnya.

Oleh karena itu, selalu gunakan jump statement (break, return, atau goto case) pada setiap switch section. Jump statement seperti kata kunci break dan return berfungsi untuk keluar dari pernyataan switch (kata kunci return biasanya digunakan di dalam pernyataan switch di dalam blok method yang mengembalikan suatu nilai). Sedangkan kata kunci goto case, berfungsi untuk melompat dari satu label case ke label case yang lain.

Contoh kode program di bawah ini menggunakan jump statement seperti break dan goto case.

class SwitchTest
{
    static void Main()
    {
        Console.WriteLine("Ukuran kopi: 1=Small 2=Medium 3=Large");
        Console.Write("Masukkan pilihan Anda: ");
        string s = Console.ReadLine();
        int n = int.Parse(s);
        int harga = 0;

        switch (n)
        {
            case 1:
                harga += 25000;
                // Keluar dari pernyataan switch
                break;
            case 2:
                harga += 25000;
                // lompat ke case 1
                goto case 1;
            case 3:
                harga += 50000;
                // lompat ke case 1
                goto case 1;
            default:
                Console.WriteLine("Pilihan tidak valid.");
                // Keluar dari pernyataan switch
                break;
        }

        if (cost != 0)
        {
            Console.WriteLine($"Masukkan Rp.{harga}.");
        }
        Console.WriteLine("Terima kasih telah menjadi pelanggan kami.");
    }
}

/*
Contoh Input:  2
 
Contoh Output:
Ukuran kopi: 1=Small 2=Medium 3=Large
Masukkan pilihan Anda: 2
Masukkan Rp.50000.
Terima kasih telah menjadi pelanggan kami.
*/

Fall Through Setup

Sebelumnya dikatakan bahwa C# tidak bisa melanjutkan eksekusi dari satu switch section ke switch section berikutnya. Lalu bagaimana jika kita ingin merespon beberapa kondisi berbeda dengan respon yang sama menggunakan percabangan switch di C#? Jawabannya, fall through setup.

Fall through setup adalah sebuah konstruksi di mana satu switch section terdiri dari dua atau lebih label case. Perhatikan kode program di bawah ini.

Console.Write("Pilih buah kesukaan Anda: ");
string pilihan = Console.ReadLine().ToLower();

switch (pilihan)
{
   case "mangga":
   case "pepaya":
   case "jeruk":
      Console.WriteLine($"Buah {pilihan} memiliki kandungan vitamin C yang tinggi");
      break;
   default:
      Console.WriteLine($"Anda memilih buah {pilihan}");
      break;
}

Dengan susunan seperti kode program di atas, jika kita memasukkan teks “mangga”, maka blok kode program yang terdapat pada label case "mangga" akan dieksekusi.

Namun, karena label case "mangga" tidak menyediakan satupun baris kode program untuk dieksekusi, maka eksekusi program akan “jatuh” ke label case "pepaya". Label ini pun tidak menyediakan satupun baris kode program untuk dieksekusi, sehingga eksekusi program akan kembali “jatuh” ke label case berikutnya yaitu, case "jeruk".

Karena pada label case "jeruk" terdapat blok kode program yang bisa dieksekusi, maka blok kode program tersebut lah yang dieksekusi.

Sederhananya, karena label case "mangga", case "pepaya", dan case "jeruk" berada di dalam satu switch section, maka ketika nilai match expression-nya cocok dengan salah satu label case pada switch section tersebut, baris kode program pada switch section tersebut akan dieksekusi.

Pencocokan Pola Dengan Pernyataan Switch (Pattern Matching)

Constant Pattern dan Type Pattern

Sejauh ini pola pada setiap label case yang kita cocokkan dengan nilai match expression-nya selalu berupa sebuah konstanta. Contohnya, teks “mangga” dan angka 1 merupakan sebuah konstanta. Di C#, ini disebut dengan constant pattern.

Sejak C# 7.0, selain menggunakan constant pattern untuk mencocokkan nilai match expression dengan nilai konstanta pada setiap label case, kita juga bisa mencocokkan tipe data yang mendasari nilai match expression-nya dengan tipe data dari variabel yang dideklarasikan di setiap label case. Di C#, ini disebut dengan type pattern.

Untuk membantu Anda memahami konsep ini, perhatikan contoh kode program di bawah ini.

Console.WriteLine("1 [Integer (5)], 2 [Double (2.5)], 3 [String (\"Hi\")]");
Console.Write("Masukkan pilihan Anda: ");
string masukan = Console.ReadLine();

// ingat bahwa tipe object dapat menyimpan nilai dari tipe apapun
object pilihanUser;

// constant pattern
switch (masukan)
{
    case "1":
        // tetapkan dengan nilai int 5
        pilihanUser = 5;
        break;
    case "2":
        // tetapkan dengan nilai double 2.5
        pilihanUser = 2.5;
        break;
    case "3":
        // tetapkan dengan nilai string "Hi"
        pilihanUser = "Hi";
        break;
    default:
        pilihanUser = 5;
        break;
}

// type pattern
switch (pilihanUser)
{
    // jika tipe dari variabel pilihanUser adalah int
    case int varInt:
        Console.WriteLine("Pilihan Anda berupa integer bernilai: {0}", varInt);
        break;
    // jika tipe dari variabel pilihanUser adalah double
    case double varDouble:
        Console.WriteLine("Pilihan Anda berupa double bernilai: {0}", varDouble);
        break;
    // jika tipe dari variabel pilihanUser adalah string
    case string varStr:
        Console.WriteLine("Pilihan Anda berupa string bernilai: {0}", varStr);
        break;
    // jika tidak ada pola yang cocok dengan tipe variabel pilihanUser
    default:
        Console.WriteLine("Anda memilih yang lain");
        break;
}

Pada kode program di atas, pengguna diminta untuk memasukkan angka 1, 2, atau 3. Nilai masukan dari pengguna kemudian disimpan kedalam variabel masukan.

Console.WriteLine("1 [Integer (5)], 2 [Double (2.5)], 3 [String (\"Hi\")]");
Console.Write("Masukkan pilihan Anda: ");
string masukan = Console.ReadLine();

Pernyataan switch pertama menggunakan constant pattern seperti biasa. Pernyataan switch ini akan mencocokkan nilai masukan dari pengguna dengan nilai konstanta yang ada pada setiap label case. Apabila ada nilai konstanta yang cocok, maka variabel pilihanUser akan ditetapkan dengan sebuah nilai.

Pernyataan switch kedua menggunakan type pattern. Tipe data yang mendasari nilai match expression pilihanUser akan dicocokkan dengan tipe data dari variabel yang dideklarasikan pada setiap label case. Untuk menggunakan type pattern, pola pada label case ditulis dengan sintaks (aturan penulisan) seperti di bawah ini.

case int varInt:

Pada label case di atas, variabel varInt di deklarasikan sebagai variabel dari tipe int.

Match expression pilihanUser nantinya akan dicocokkan dengan setiap variabel yang dideklarasikan pada masing-masing label case. Apabila terdapat variabel dari tipe data yang sama dengan tipe data yang mendasari nilai dari pilihanUser, maka nilai dari pilihanUser akan disimpan di dalam variabel tersebut.

Katakan pilihanUser bernilai 5 yang mana merupakan bilangan dari tipe int. Dengan demikian, pola pada label case yang cocok dengan kondisi ini adalah case int varInt, karena tipe data yang mendasari nilai pilihanUser adalah juga dari tipe int. Selanjutnya nilai dari pilihanUser, yaitu angka 5, ditetapkan kedalam variabel varInt. Dengan demikian, variabel varInt bisa digunakan pada saat mengeksekusi switch section pada pernyataan case int varInt.

Console.WriteLine("Pilihan Anda berupa integer bernilai: {0}", varInt);

Klausa “when” Pada Percabangan Swicth

Masih ingat kode program yang kita pelajari di materi percabangan if di C# sebelumnya?

nilai = 79;
if (nilai >= 0 & nilai < 20)
{
    Console.WriteLine("Nilai Anda: E");
}
else if (nilai >= 20 & nilai < 40)
{
    Console.WriteLine("Nilai Anda: D");
}
else if (nilai >= 40 & nilai < 60)
{
    Console.WriteLine("Nilai Anda: C");
}
else if (nilai >= 60 & nilai < 80)
{
    Console.WriteLine("Nilai Anda: B");
}
else if (nilai >= 80 & nilai <= 100)
{
    Console.WriteLine("Nilai Anda: A");
}
else
{
    Console.WriteLine("Nilai yang diberikan berada di luar rentang yang dimungkinkan");
}

Pertanyaannya, bagaimana kita mengubah kode program di atas menggunakan pernyataan switch? Kali ini, mengubah pernyataan if – else if seperti di atas tidak sesimpel mengubah pernyataan if – else if seperti yang telah kita lakukan di awal materi ini. Karena kali ini terdapat dua buah kondisi untuk setiap pernyataan if dan else if yang harus dipenuhi.

Dengan adanya dua kondisi untuk setiap pernyataan if dan else if seperti ini, kita tidak bisa menggunakan pola pernyataan switch yang telah kita pelajari sampai saat ini.

Permasalahan ini mulai C# 7.0 bisa kita atasi dengan menggunakan type pattern bersamaan dengan klausa when, seperti yang ditunjukkan oleh kode program di bawah ini.

Console.Write("Masukkan nilai angka: ");
string inputNilai = Console.ReadLine();
nilai = int.TryParse(inputNilai, out int n) ? n : -1;

switch (nilai)
{
    case int x when x >= 0 & x < 20:
        Console.WriteLine("Nilai Anda: E");
        break;
    case int x when x >= 20 & x < 40:
        Console.WriteLine("Nilai Anda: D");
        break;
    case int x when x >= 40 & x < 60:
        Console.WriteLine("Nilai Anda: C");
        break;
    case int x when x >= 60 & x < 80:
        Console.WriteLine("Nilai Anda: B");
        break;
    case int x when x >= 80 & x <= 100:
        Console.WriteLine("Nilai Anda: A");
        break;
    default:
        Console.WriteLine("Nilai yang Anda masukkan tidak dapat dikonversi ke nilai huruf");
        break;
}

Pada kode program di atas, masukan dari pengguna terlebih dahulu kita konversi ke nilai int dengan method TryParse(). Untuk menetapkan nilai variabel nilai, kita menggunakan operator ternary. Jika sebuah nilai berhasil dikonversi ke tipe int, maka nilai tersebut akan ditetapkan ke variabel nilai. Namun jika konversi gagal dilakukan, maka variabel nilai akan ditetapkan dengan nilai -1.

nilai = int.TryParse(inputNilai, out int n) ? n : -1;

Perhatikan bahwa kali ini kita menggunakan pola tipe data yang sama untuk setiap label case, yaitu case int x. Hanya saja, kali ini kita juga menambahkan klausa when di setiap pernyataan pada label case.

Tentu saja karena nilai dari match expression-nya, dalam hal ini variabel nilai, adalah dari tipe int, maka semua pola label case pada kode program di atas akan memenuhi kondisi tersebut. Namun karena kita memberikan kondisi tambahan dengan klausa when yang juga harus dipenuhi, maka kondisi tambahan tersebut juga harus terpenuhi terlebih dahulu agar switch section di dalamnya dapat dieksekusi.

Katakan masukan yang kita berikan adalah angka 75, maka keluaran dari program di atas adalah:

Nilai Anda: B

Penutup

Pada materi kali ini, kita sudah mempelajari bagaimana mengatur alur eksekusi dengan percabangan switch di C#.

Percabangan switch bisa kita gunakan sebagai alternatif percabangan if dengan pernyataan if – else if, di mana kita perlu mengevaluasi beberapa kondisi terlebih dahulu sebelum memutuskan baris kode program yang mana yang akan dieksekusi.

Mengatur alur eksekusi dengan percabangan switch di C# bisa dilakukan dengan menggunakan baik constant pattern maupun type pattern. Dengan menggunakan type pattern, Anda bisa menggunakan klausa when untuk memberi tambahan kondisi untuk setiap switch section.

Jika Anda masih merasa kesulitan dalam memahami materi ini, jangan menyerah! Tulis kesulitan atau pertanyaan Anda di kolom komentar, saya akan membantu.

Selamat belajar!

This Post Has 2 Comments
  1. Faishal

    Yang when ko eror

    1. Dian Nandiwardhana

      Halo Mas Faishal!

      Erornya sebelah mana ya? Pesan erornya apa?

Tinggalkan Balasan