Pattern matching menguji bentuk dan isi sebuah nilai sekaligus, lalu mengekstrak datanya ke variabel baru dalam satu langkah. Dibanding perbandingan biasa, pattern matching menjawab pertanyaan seperti: apakah sebuah object bertipe int, apakah panjang sebuah string mencukupi, atau apakah dua nilai memenuhi syarat yang berpasangan.

Type Pattern dengan Operator is #

Type pattern memeriksa tipe runtime sebuah nilai dan mengikat nilainya ke variabel baru bertipe tersebut. Bentuk paling sederhana memakai operator is di dalam statement if.

csharp
object kotak = 42;

if (kotak is int angka)
{
    Console.WriteLine($"Kotak berisi angka {angka}");
}

Output yang Dihasilkan:

text
Kotak berisi angka 42

Variabel kotak dideklarasikan sebagai object, sehingga compiler saat kompilasi tidak mengetahui isinya. Pada saat program berjalan, operator is menguji tipe sebenarnya: karena isinya 42 bertipe int, pattern cocok dan variabel baru angka yang bertipe int hanya terlihat di dalam blok if.

Type pattern juga bisa dipakai di dalam switch expression untuk mengelompokkan isi koleksi campuran:

csharp
List<object> tumpukan = new List<object> { "Buku", 25000, 'A', 3.5 };

foreach (object item in tumpukan)
{
    string jenis = item switch
    {
        string teks => $"Teks: {teks}",
        int bilangan => $"Bilangan bulat: {bilangan}",
        _ => "Tipe lain"
    };
    Console.WriteLine(jenis);
}

Output yang Dihasilkan:

text
Teks: Buku
Bilangan bulat: 25000
Tipe lain
Tipe lain

Mari kita telaah baris demi baris:

  1. Baris 1 (List<object> tumpukan): Empat nilai bertipe berbeda disimpan dalam satu list; setiap nilai disimpan sebagai object.
  2. Baris 3 (foreach (object item in tumpukan)): Foreach loop mengunjungi elemen satu per satu, dan tipe runtime tiap elemen tetap utuh meski variabelnya object.
  3. Baris 7 (string teks => ...): Type pattern menguji apakah elemen bertipe string; bila cocok, nilai terikat ke variabel teks.
  4. Baris 8 (int bilangan => ...): Pattern serupa untuk int; elemen 25000 cocok di sini.
  5. Baris 9 (_ => "Tipe lain"): Discard menampung elemen 'A' bertipe char dan 3.5 bertipe double yang tidak cocok dengan dua type pattern di atas.

Logical Pattern not dan Property Pattern #

Operator not membalik hasil pencocokan: pola stok is not 0 bernilai true bila stok bukan nol. Sementara itu, property pattern memeriksa nilai properti dari sebuah objek dengan penulisan { NamaProperti: pola }.

csharp
int stok = 0;

if (stok is not 0)
{
    Console.WriteLine("Stok tersedia");
}
else
{
    Console.WriteLine("Stok kosong");
}

string sandi = "belajar123";

string kekuatan = sandi switch
{
    { Length: 0 } => "Kosong",
    { Length: < 8 } => "Lemah",
    _ => "Kuat"
};

Console.WriteLine($"Sandi {sandi}: {kekuatan}");

Output yang Dihasilkan:

text
Stok kosong
Sandi belajar123: Kuat

Setiap string memiliki properti Length, sehingga arm { Length: 0 } mendeteksi string kosong dan arm { Length: < 8 } menggabungkan property pattern dengan relational pattern. String "belajar123" memiliki panjang 10, sehingga jatuh ke discard dan dinilai Kuat.

Tuple Pattern #

Tuple pattern menguji beberapa nilai sekaligus berdasarkan posisinya, dan pola pada setiap posisi boleh berbeda-beda.

csharp
int kehadiran = 90;
int nilaiUjian = 70;

string hasil = (kehadiran, nilaiUjian) switch
{
    (>= 75, >= 70) => "Lulus",
    (>= 75, < 70) => "Remedial",
    _ => "Tidak lulus"
};

Console.WriteLine(hasil);

Output yang Dihasilkan:

text
Lulus

Pattern pertama menuntut kehadiran >= 75 pada posisi pertama dan nilaiUjian >= 70 pada posisi kedua. Nilai 90 dan 70 memenuhi keduanya, sehingga hasilnya Lulus tanpa perlu menulis if bersarang.