Menu

Pernyataan switch di C#: case, break, default dan Banyak Case

Cara kerja pernyataan switch di C#: switch pada nilai int, string, char, dan enum, kenapa setiap case butuh break (error CS0163), menumpuk label case untuk beberapa nilai, goto case, default, kepekaan huruf besar kecil pada string, dan label case berpola dengan when.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Pernyataan switch membandingkan satu nilai dengan daftar label case berupa konstanta, lalu menjalankan bagian yang cocok. Di C#, setiap bagian harus diakhiri break (atau pernyataan lain yang keluar dari bagian itu), jadi satu case tidak pernah bisa diam-diam berlanjut ke case berikutnya.

Output:

200: OK
302: redirect
404: not found
500: unhandled status

Nilai di dalam tanda kurung dievaluasi sekali, lalu dibandingkan dengan setiap label. default dijalankan jika tidak ada yang cocok; bagian ini bersifat opsional dan boleh muncul di mana saja dalam daftar, meskipun biasanya ditaruh paling akhir. Jika tidak ada yang cocok dan tidak ada default, seluruh switch tidak melakukan apa-apa.

Setiap bagian butuh break

Di C, C++, Java, dan JavaScript, lupa menulis break membuat eksekusi meluncur ke case berikutnya. C# mengubah kesalahan itu menjadi error kompilasi:

switch (level)
{
    case 1:
        Console.WriteLine("read");
        // error CS0163: Control cannot fall through from one case label ('case 1:') to another
    case 2:
        Console.WriteLine("write");
        break;
}

Aturannya, akhir daftar pernyataan sebuah bagian tidak boleh bisa dicapai. break adalah cara biasa untuk memenuhinya, tetapi apa pun yang keluar dari bagian itu juga berfungsi:

  • return keluar dari seluruh method, dan sering menjadi bentuk paling rapi di dalam helper kecil.
  • throw melempar exception untuk nilai yang seharusnya tidak pernah muncul.
  • continue melompat ke iterasi berikutnya jika switch berada di dalam perulangan.
  • goto case dan goto default sengaja melompat ke bagian lain.

Bagian terakhir tidak dikecualikan. default: di paling bawah tanpa break gagal dengan CS8070, Control cannot fall out of switch from final case label ('default:').

Beberapa nilai dalam satu case

Label yang tidak punya pernyataan di antaranya berbagi bagian di bawahnya. Inilah satu-satunya jenis fall through yang diizinkan C#, karena label kosong tidak bisa menyembunyikan kode apa pun:

Output:

'O' is a vowel
'k' is a consonant or symbol
' ' is a space
'7' is a digit

Setiap bagian di sini diakhiri return, jadi tidak perlu break (break setelah return akan menjadi kode yang tidak bisa dicapai). Dua label dengan nilai yang sama adalah error, CS0152 The switch statement contains multiple cases with the label value '1', dan setiap label harus berupa konstanta saat kompilasi: variabel di sebuah case gagal dengan pesan "a constant value is expected".

Switch pada string

String adalah nilai switch yang paling umum setelah bilangan bulat. Perbandingannya ordinal dan peka huruf besar kecil, jadi normalisasi input-nya sebelum melakukan switch:

Output:

Starting the server
Stopping the server
Server is running
Unknown command: restart
Unknown command: (none)

Tanpa ToLowerInvariant, "STOP" akan sampai ke default. Nilai null sah dipakai untuk switch: nilai itu tidak cocok dengan konstanta string mana pun dan jatuh ke default, jadi switch-nya sendiri tidak pernah melempar exception.

Switch pada enum

Enum adalah alasan switch dibuat: kumpulan nilai bernama yang tertutup.

Output:

Pending: wait for payment
Paid: pack and ship
Shipped: track the parcel
Delivered: nothing, order is closed
Cancelled: nothing, order is closed
ArgumentOutOfRangeException for value 42

Compiler tidak memeriksa apakah pernyataan switch mencakup setiap member enum, dan variabel enum bisa berisi bilangan bulat apa pun dari tipe dasarnya ((OrderStatus)42 itu sah). default yang melempar exception mengubah case yang terlupa menjadi kegagalan yang langsung dan jelas, bukan sesuatu yang diam-diam tidak melakukan apa-apa.

goto case dan goto default

Jika satu case memang harus berlanjut ke case lain, C# membuatmu menuliskan lompatannya:

Output:

admin:
  manage users
  edit posts
  read posts
editor:
  edit posts
  read posts
guest:
  read posts

goto case menerima sebuah konstanta yang harus cocok dengan salah satu label di switch yang sama. Ini jarang dipakai di kode sungguhan: perilaku bersama biasanya lebih jelas jika dijadikan method yang dipanggil beberapa case. Tetapi inilah jawaban untuk "bagaimana cara melakukan fall through di C#".

Variabel di dalam case

Seluruh blok switch adalah satu cakupan, jadi dua case tidak bisa mendeklarasikan variabel dengan nama yang sama:

switch (shape)
{
    case "square":
        int area = side * side;
        break;
    case "rectangle":
        int area = width * height;   // error CS0128: A local variable or function named 'area' is already defined in this scope
        break;
}

Bungkus body setiap bagian dengan kurung kurawal agar punya cakupannya sendiri: case "square": { int area = side * side; ... break; }.

break di dalam perulangan

break di sebuah case keluar dari switch, bukan dari perulangan di sekitarnya. continue melakukan kebalikannya: switch bukan perulangan, jadi continue menuju iterasi berikutnya dari perulangan itu.

Output:

end marker found
Total: 134

Perulangannya tetap berjalan setelah "end" dan menambahkan 99. Untuk menghentikan perulangan dari dalam switch, isi sebuah flag lalu periksa setelah switch, atau pindahkan perulangan ke sebuah method lalu return. Halaman break dan continue membandingkan pilihan-pilihannya.

Label case berpola dan when

Sejak C# 7.0, label case bisa berupa pola, bukan hanya konstanta: label itu bisa menguji tipe nilainya dan menambahkan kondisi when. Bentuk ini umum di kode C# modern:

static string Describe(object value)
{
    switch (value)
    {
        case null:
            return "nothing";
        case int n when n < 0:
            return $"negative int {n}";
        case int n:
            return $"int {n}";
        case string s when s.Length == 0:
            return "empty string";
        case string s:
            return $"string \"{s}\"";
        default:
            return $"other: {value.GetType().Name}";
    }
}

Dengan pola, urutan itu penting: case pertama yang cocok yang menang, dan compiler melaporkan error jika sebuah case tidak akan pernah tercapai karena case sebelumnya sudah mencakupnya (menaruh case int n: di atas case int n when n < 0: akan gagal). Klausa when juga bisa dipakai pada case konstanta: case 0 when isAdmin:. C# 9 menambahkan pola relasional dan logika, jadi sebuah case bisa ditulis case >= 90: atau case 'a' or 'e' or 'i':.

Di C# 7 tanpa pola, pemilihan berdasarkan tipe yang sama ditulis sebagai rangkaian if dengan pola tipe is:

Output:

negative int -3
int 12
empty string
string "hi"
other: Decimal
nothing

Jika setiap cabang switch hanya menghitung sebuah nilai, ekspresi switch lebih ringkas lagi: var grade = score switch { >= 90 => "A", >= 80 => "B", _ => "C" };. Halaman ekspresi switch membahas sintaks, pola, dan aturan exhaustiveness-nya.

Nilai yang bisa dipakai untuk switch

Tipe nilaiCase konstantaCatatan
int, long, byte, dan bilangan bulat lainnyayakasus klasik
charyacase 'a':
stringyaordinal, peka huruf besar kecil, null masuk ke default
boolyasah, tetapi if lebih jelas
enum apa punyatanpa pengecekan exhaustiveness
double, decimalsejak C# 7hanya konstanta; rentang butuh pola relasional C# 9
tipe lain apa punsejak C# 7lewat pola tipe, case Circle c:

Pertanyaan yang sering diajukan

Apakah break wajib di switch C#?

Setiap bagian case harus diakhiri pernyataan yang keluar dari bagian itu: biasanya break, tetapi return, throw, continue (di dalam perulangan), atau goto case juga dihitung. Jatuh dari akhir sebuah bagian ke bagian berikutnya adalah error kompilasi, CS0163 Control cannot fall through from one case label ('case 1:') to another, dan itu juga berlaku untuk bagian terakhir.

Bagaimana cara menangani beberapa nilai dalam satu case switch C#?

Tumpuk label-labelnya tanpa apa pun di antaranya: case "sat": case "sun": Console.WriteLine("weekend"); break;. Label case yang kosong boleh jatuh ke label berikutnya; hanya bagian yang berisi pernyataan yang wajib diakhiri break. Di C# 9 dan sesudahnya, case berpola juga bisa ditulis case 1 or 2 or 3:.

Apakah switch pada string di C# peka huruf besar kecil?

Ya. Case string dibandingkan dengan kesamaan ordinal yang peka huruf besar kecil, jadi "Yes" tidak cocok dengan case "yes":. Normalisasi nilainya lebih dulu dengan switch (input.Trim().ToLowerInvariant()). String null tidak cocok dengan case konstanta mana pun dan masuk ke default.

Bisakah switch C# melakukan fall through seperti di C atau Java?

Tidak secara implisit. Jika kamu ingin satu case berlanjut ke case lain, nyatakan dengan goto case <value>; atau goto default;. Dengan begitu, setiap fall through terlihat jelas di kode, itulah sebabnya C# melarang versi yang diam-diam.

Apa perbedaan pernyataan switch dan ekspresi switch di C#?

Pernyataan switch menjalankan pernyataan dan butuh case, break, dan default. Ekspresi switch (C# 8 dan sesudahnya) menghasilkan sebuah nilai: var label = n switch { 0 => "zero", > 0 => "positive", _ => "negative" };. Pakai ekspresi jika setiap cabang hanya menghitung sebuah hasil.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai