Rantai data sering kali berisi tautan yang mungkin kosong: pesanan tanpa pembeli, pembeli tanpa kota, atau array yang belum dialokasikan. Memeriksa setiap tautan dengan if membuat kode panjang dan mudah terlewat satu cabang. Operator null-conditional ?. menyingkat pemeriksaan itu menjadi satu karakter yang menyertai setiap tautan berisiko.
Mekanisme Propagasi Null #
Expression x?.Y dibaca: bila x tidak null, hasilnya x.Y; bila x bernilai null, seluruh rantai berhenti dan hasilnya null tanpa mengeksekusi Y. Section Operator sudah memperkenalkan operator ini secara ringkas; di sini kita menekankan dua konsekuensi teknisnya. Pertama, rantai berhenti pada tautan kosong pertama, sehingga tautan setelahnya tidak dievaluasi. Kedua, bila anggota akhir bertipe value type, hasilnya menjadi nullable, misalnya int? untuk Length.
Contoh: Rantai Data Pesanan #
public record Pelanggan(string Nama, string? Kota);
public record Pesanan(string Nomor, Pelanggan? Pembeli);
Pesanan pesanan1 = new Pesanan("ORD-2001", new Pelanggan("Budi Santoso", "Bandung"));
Pesanan pesanan2 = new Pesanan("ORD-2002", null);
Console.WriteLine($"Pembeli 1: {pesanan1.Pembeli?.Nama ?? "(tanpa pembeli)"}");
Console.WriteLine($"Kota 1: {pesanan1.Pembeli?.Kota ?? "(kota belum diisi)"}");
Console.WriteLine($"Pembeli 2: {pesanan2.Pembeli?.Nama ?? "(tanpa pembeli)"}");
int? panjangKota = pesanan2.Pembeli?.Kota?.Length;
Console.WriteLine($"Panjang kota 2: {panjangKota?.ToString() ?? "null"}");
string[]? daftarGudang = null;
Console.WriteLine($"Gudang pertama: {daftarGudang?[0] ?? "(array masih null)"}");Output yang Dihasilkan:
Pembeli 1: Budi Santoso
Kota 1: Bandung
Pembeli 2: (tanpa pembeli)
Panjang kota 2: null
Gudang pertama: (array masih null)Mari kita bedah baris demi baris:
record Pesanan(string Nomor, Pelanggan? Pembeli): AnotasiPelanggan?menyatakan pesanan boleh tanpa pembeli, dan itulah kondisi yang diantisipasi operator?..pesanan1.Pembeli?.Nama ?? "(tanpa pembeli)":Pembeliterisi, sehingga rantai berlanjut keNamadan mencetak nilai aslinya.pesanan2.Pembeli?.Nama:Pembelibernilainull, sehinggaNamatidak dievaluasi dan hasilnyanull; operator??menggantinya dengan teks penanda.pesanan2.Pembeli?.Kota?.Length: Setiap tautan membawa?.sendiri. Rantai berhenti diPembeli, sehingga hasil bertipeint?bernilainull.panjangKota?.ToString() ?? "null": Value typeint?tidak bisa langsung digabung?? string, sehingga hasil dikonversi dulu lewatToString().daftarGudang?[0]: Bentuk?[]melindungi pengindeksan; array yangnullmenghasilkannull, bukan exception.
Padanan dengan Pemeriksaan Manual #
Expression pesanan2.Pembeli?.Nama setara dengan blok if (pesanan2.Pembeli is not null) { ... } yang mengembalikan null pada cabang lain. Perbedaannya terletak pada kepadatan: satu operator menggantikan satu percabangan, dan beberapa operator berderet tetap mudah dibaca.