Bab Required Members di section Properties dan Encapsulation membahas modifier required pada property: compiler menolak object initializer yang tidak mengisi anggota tersebut. Bab ini menuntaskan sisi lanjutannya. Modifier yang sama berlaku pada field, constructor beratribut [SetsRequiredMembers] membebaskan pemanggil dari initializer, dan with pada record memenuhi kontrak secara otomatis karena menyalin anggota dari instance sebelumnya.

Mekanisme pada Tiga Bentuk #

  • Field biasa dapat ditandai required, sehingga struct sederhana pun menuntut isian awal tanpa perlu property.
  • Atribut [SetsRequiredMembers] pada constructor memberi tanda bahwa constructor itu sudah mengisi seluruh anggota required; pemanggilnya boleh menulis new Akun(email) tanpa initializer.
  • with-expression pada record menyalin semua anggota, termasuk yang required, sehingga instance hasil with otomatis memenuhi kontrak yang sama.

Contoh: Record, Struct, dan Constructor #

csharp
var buku = new Produk { Kode = "B-101", Harga = 85000 };
Console.WriteLine($"{buku.Kode} {buku.Harga}");

var murah = buku with { Harga = 70000 };
Console.WriteLine($"{murah.Kode} {murah.Harga}");

Titik t = new Titik { X = 3, Y = 4 };
Console.WriteLine($"{t.X} {t.Y}");

Akun a = new Akun("[email protected]");
Console.WriteLine(a.Email);

Output yang Dihasilkan:

text
B-101 85000
B-101 70000
3 4
[email protected]

Mari kita bedah baris demi baris:

  1. new Produk { ... }: property Kode dan Harga ditandai required dengan aksesor init; menghilangkan salah satunya menghentikan kompilasi.
  2. buku with { Harga = 70000 }: with menyalin Kode dari instance asal, sehingga kontrak required terpenuhi tanpa menuliskannya kembali.
  3. Titik { X = 3, Y = 4 }: pada struct, required dipasang di field; kedua field wajib ada di initializer karena tidak ada nilai bawaan yang memenuhi kontrak.
  4. new Akun("[email protected]"): constructor ini beratribut [SetsRequiredMembers] dan mengisi Email di badannya, sehingga pemanggil tidak menulis initializer sama sekali.

Implikasi untuk Pustaka #

Kontrak required disimpan di metadata dan diperiksa compiler pemanggil. Pustaka yang menambahkan anggota required pada versi baru berpotensi membuat kode pemanggil lama gagal dikompilasi, karena initializer lama tidak mengisi anggota tersebut. Constructor beratribut [SetsRequiredMembers] menjadi jalur migrasi yang rapi: anggota baru diisi di dalam constructor, dan pemanggil lama tetap berjalan tanpa perubahan.