Event field-like pada bab-bab sebelumnya menyembunyikan backing field dan accessors di dalam compiler. Ketika kita perlu mengawasi setiap perubahan langganan, misalnya mencatat jumlah subscriber alarm stok, deklarasikan event dengan accessor add dan remove. Sejak saat itu, backing field menjadi tanggung jawab kita sendiri.
Ketika accessor ditulis manual, compiler berhenti membuat backing field dan pengamanan otomatis. Kebebasan ini dibayar dengan disiplin: field harus kita deklarasikan sendiri, dan setiap accessor wajib menyentuhnya. Pola yang sama dipakai framework untuk memvalidasi handler, mencatat statistik langganan, atau menambah logika thread-safety pada event yang diakses lintas thread.
Accessor add dan remove #
class AlarmStok
{
private EventHandler _stokKritis;
public int JumlahSubscriber => _stokKritis?.GetInvocationList().Length ?? 0;
public event EventHandler StokKritis
{
add
{
_stokKritis += value;
Console.WriteLine($"Subscriber baru ditambahkan (total {JumlahSubscriber})");
}
remove
{
_stokKritis -= value;
Console.WriteLine($"Subscriber dilepas (sisa {JumlahSubscriber})");
}
}
public void NaikkanAlarm()
{
_stokKritis?.Invoke(this, EventArgs.Empty);
}
}
AlarmStok alarm = new();
EventHandler catat = (pengirim, e) => Console.WriteLine("Laporan: stok kritis tercatat");
EventHandler pesan = (pengirim, e) => Console.WriteLine("Pesan: minta restock segera");
alarm.StokKritis += catat;
alarm.StokKritis += pesan;
alarm.NaikkanAlarm();
alarm.StokKritis -= pesan;Output yang Dihasilkan:
Subscriber baru ditambahkan (total 1)
Subscriber baru ditambahkan (total 2)
Laporan: stok kritis tercatat
Pesan: minta restock segera
Subscriber dilepas (sisa 1)Bedah Kode Baris per Baris #
Mari kita telaah kode di atas:
- Baris 3: Field privat
_stokKritismenyimpan daftar handler; compiler tidak lagi membuatnya untuk kita. - Baris 5: Properti
JumlahSubscribermembaca panjang invocation list, sehingga kode lain dapat memeriksa beban alarm tanpa menyentuh field. - Baris 7-18: Accessor
adddanremovemenerima handler sebagai keywordvalue. Setiap operasi dicatat, dan jumlah subscriber terbaru ikut tercetak. - Baris 25-26: Dua lambda pertama dipegang variabel
catatdanpesanagar-=pada baris terakhir dapat menghapus handler yang tepat. - Baris 29:
NaikkanAlarmmemicu event denganEventArgs.Emptykarena alarm tidak membawa data tambahan. - Baris 30: Melepas
pesanjuga melewati accessorremove, terbukti dari baris outputSubscriber dilepas (sisa 1).
Perhatikan bahwa lambda catat dan pesan dipegang variabel terlebih dahulu. Dua lambda dengan isi yang sama tetap merupakan dua objek handler yang berbeda, sehingga -= terhadap lambda baru yang ditulis langsung tidak akan menghapus pendaftaran lama.