Auto-implemented property menyembunyikan backing field-nya, dan kita tidak dapat menyentuh penyimpanan itu dari kode sendiri. Batas tersebut terasa ketika dua property perlu menopang satu data yang sama, atau ketika aksesor butuh menyimpan keadaan tambahan. Untuk kasus seperti itu, kita kembali ke pola dasar: menulis field privat secara manual dan menghubungkannya ke property. Bab ini membahas kapan backing field manual diperlukan dan cara menghubungkannya dengan benar.

Masalah: Satu Data, Dua Sudut Pandang #

Class Suhu perlu menawarkan pembacaan dalam Celsius sekaligus Fahrenheit. Bila keduanya dibuat sebagai dua auto-property terpisah, class menyimpan dua salinan data yang berbeda satuan, dan setiap perubahan pada satu property menuntut konversi manual ke property lainnya. Kelalaian satu penugasan membuat kedua satuan menampilkan suhu yang berbeda. Solusinya adalah satu penyimpanan tunggal yang menopang dua sudut pandang.

Mekanisme Backing Field Manual #

Backing field manual mengikuti tiga aturan:

  • Field dideklarasikan private dan hanya diakses lewat aksesor; kode luar tidak mengetahui keberadaannya.
  • Property penyimpan, yaitu Celsius, membaca dan menulis field secara langsung.
  • Property turunan, yaitu Fahrenheit, juga membaca dan menulis field yang sama, tetapi mengonversi nilainya bolak-balik.

Karena kedua property berbagi satu field, tidak ada dua salinan yang dapat saling bertentangan. Auto-property tidak bisa meniru pola ini karena backing field milik compiler tidak dapat dirujuk dan tidak dapat dibagikan.

Contoh: Class Suhu dengan Dua Satuan #

csharp
public class Suhu
{
    private double celsius;

    public double Celsius
    {
        get { return celsius; }
        set { celsius = value; }
    }

    public double Fahrenheit
    {
        get { return celsius * 9.0 / 5.0 + 32.0; }
        set { celsius = (value - 32.0) * 5.0 / 9.0; }
    }
}

Suhu suhu = new Suhu();
suhu.Celsius = 25;
Console.WriteLine($"Fahrenheit dari 25 C: {suhu.Fahrenheit}");

suhu.Fahrenheit = 212;
Console.WriteLine($"Celsius dari 212 F: {suhu.Celsius}");

Output yang Dihasilkan:

text
Fahrenheit dari 25 C: 77
Celsius dari 212 F: 100

Mari kita bedah baris demi baris:

  1. private double celsius;: satu field manual menjadi satu-satunya penyimpan data; kedua property menopang nilai yang sama dari sisi berbeda.
  2. Aksesor milik Celsius: property penyimpan menyalin nilai bolak-balik tanpa perubahan, sebagaimana property biasa.
  3. get { return celsius * 9.0 / 5.0 + 32.0; }: pembacaan Fahrenheit mengonversi isi field saat itu juga, sehingga hasilnya selalu cocok dengan Celsius.
  4. set { celsius = (value - 32.0) * 5.0 / 9.0; }: penugasan pada Fahrenheit dikonversi mundur ke Celsius sebelum disimpan; suhu.Fahrenheit = 212 membuat field celsius berisi 100.
  5. Console.WriteLine($"Celsius dari 212 F: {suhu.Celsius}");: pembacaan lewat property lain menunjukkan kedua satuan menunjuk satu data yang sama.