Variabel bertipe reference bisa berada dalam keadaan null, yaitu tidak menunjuk data apa pun. Kondisi ini lazim terjadi: nama pelanggan belum diisi, hasil pencarian tidak menemukan data, atau konfigurasi opsional belum diset. Masalah muncul ketika program mengakses anggota variabel null; runtime melempar NullReferenceException dan program berhenti. C# menyediakan tiga operator yang menangani null secara ringkas: ??, ??=, dan ?..

Operator ?? (Null-Coalescing) #

Operator ?? membaca: “ambil nilai kiri bila tidak null, selain itu ambil nilai kanan”. Bentuknya kiri ?? kanan. Bila kiri tidak null, hasilnya nilai kiri dan kanan tidak dievaluasi. Bila kiri bernilai null, hasilnya nilai kanan. Pola ini umum dipakai untuk memberi nilai default.

Operator ??= #

Bentuk ??= menggabungkan penugasan dengan ??. Expression variabel ??= nilai mengisi variabel dengan nilai hanya bila variabel masih null; bila variabel sudah berisi data, penugasan itu tidak terjadi.

Operator ?. (Null-Conditional) #

Operator ?. memanggil anggota hanya bila penerima tidak null. Bila penerima bernilai null, seluruh rantai pemanggilan berhenti dan hasilnya null, tanpa melempar exception.

Contoh dan Bedah Baris #

csharp
string? kota = null;
Console.WriteLine(kota ?? "(belum diisi)");

kota ??= "Bandung";
Console.WriteLine(kota);
kota ??= "Surabaya";
Console.WriteLine(kota);

string? nama = null;
Console.WriteLine(nama?.Length ?? 0);
Console.WriteLine(nama?.ToUpper() ?? "(nama kosong)");

nama = "Siti";
Console.WriteLine(nama?.Length ?? 0);
Console.WriteLine(nama?.ToUpper() ?? "(nama kosong)");

Output yang Dihasilkan:

text
(belum diisi)
Bandung
Bandung
0
(nama kosong)
4
SITI

Mari kita telaah baris demi baris:

  1. Baris 1 (string? kota = null;): Tanda string? menyatakan variabel kota boleh bernilai null; nilai awalnya memang null.
  2. Baris 2 (kota ?? "(belum diisi)"): kota masih null, sehingga cabang kanan "(belum diisi)" yang tercetak.
  3. Baris 4-6 (??=): Penugasan pertama mengisi kota dengan "Bandung" karena kota masih null; penugasan kedua tidak berpengaruh karena kota sudah berisi data, sehingga Bandung tetap tercetak.
  4. Baris 9-10 (?. pada nama): nama bernilai null, sehingga nama?.Length menghasilkan null, lalu ?? 0 menggantinya dengan 0; pola yang sama membuat "(nama kosong)" tercetak.
  5. Baris 12-13 (setelah nama = "Siti"): nama tidak lagi null; nama?.Length menghasilkan 4 dan nama?.ToUpper() menghasilkan SITI.

Kapan Ketiganya Dipakai #

Ketiga operator ini melengkapi satu sama lain dalam pola yang berbeda:

  • ?? memberi nilai pengganti saat dibaca: Console.WriteLine(alias ?? "(tanpa alias)").
  • ??= mengisi data sekali saja, cocok untuk nilai bawaan: konfigurasi ??= nilaiAwal;.
  • ?. mengamati data yang mungkin kosong tanpa melempar exception: pesanan?.Kode.

Membaca nilai null dengan ?? tidak sama dengan membandingkan kebenaran teks. Operator ini hanya menguji satu hal: apakah variabel bernilai null atau tidak; string kosong "" tetap dianggap berisi data dan tidak digantikan nilai kanan.