Beberapa data class memang ditentukan sekali di awal dan tidak boleh berubah lagi, misalnya alamat server dan port pada object konfigurasi. Get-only property menutup akses tulis, tetapi cara tersebut menuntut kita menyediakan constructor berparameter untuk setiap nilai awal. Sejak C# 9, aksesor init memberi jalan tengah: property dapat diisi saat object dibuat, lalu tertutup untuk penugasan berikutnya.

Masalah: Nilai yang Hanya Boleh Diisi Sekali #

Dua pilihan lama sama-sama kurang nyaman. Property dengan set tetap terbuka sehingga kode luar dapat mengubah konfigurasi di tengah program. Sebaliknya, get-only property memaksa kita menulis constructor yang menyalin setiap parameter ke field satu per satu, dan jumlah baris itu bertambah setiap konfigurasi bertambah. Kita butuh akses tulis yang hanya hidup selama proses pembuatan object.

Mekanisme Aksesor init #

Aksesor init menggantikan aksesor set pada deklarasi property:

  • Compiler memperbolehkan penugasan ke property init hanya di dalam object initializer atau di dalam constructor class yang bersangkutan.
  • Setelah fase pembuatan object selesai, setiap penugasan baru dari kode luar gagal dikompilasi, bukan gagal saat runtime.
  • init sering dipasangkan dengan auto-property, menghasilkan deklarasi { get; init; } yang ringkas dan aman.

Dengan pola ini, pembaca kode langsung melihat dari deklarasi bahwa nilai property dimaksudkan tetap untuk sisa masa program.

Contoh: Konfigurasi Server #

csharp
public class Konfigurasi
{
    public string AlamatServer { get; init; }
    public int Port { get; init; }
}

Konfigurasi konfigurasi = new Konfigurasi
{
    AlamatServer = "api.example.com",
    Port = 8080
};

Console.WriteLine($"Server: {konfigurasi.AlamatServer}");
Console.WriteLine($"Port: {konfigurasi.Port}");

Output yang Dihasilkan:

text
Server: api.example.com
Port: 8080

Mari kita bedah baris demi baris:

  1. public string AlamatServer { get; init; }: property auto-implemented dengan akses baca penuh dan akses tulis yang dibatasi fase pembuatan object.
  2. new Konfigurasi { AlamatServer = ..., Port = 8080 }: object initializer adalah satu-satunya tempat penugasan init diizinkan bagi kode luar; compiler menerima penugasan tersebut karena object sedang dibuat.
  3. Console.WriteLine($"Server: {konfigurasi.AlamatServer}");: pembacaan property init berperilaku sama seperti property set, sehingga kode pemakai tidak merasakan bedanya.
text
error CS8852: Init-only property or indexer 'Konfigurasi.Port' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor.

Pola { get; init; } menjadi dasar bagi modifier required pada bab berikutnya, yang menambahkan aturan wajib isi pada fase pembuatan object yang sama.