Ini adalah kasus abstraksi yang bocor. Properti sebenarnya adalah metode, get dan set aksesor untuk pengindeks dikompilasi ke metode get_Index () dan set_Index. Kompilator melakukan pekerjaan yang hebat menyembunyikan fakta itu, secara otomatis menerjemahkan sebuah tugas ke sebuah properti ke metode set_Xxx () yang sesuai misalnya.
Tapi ini akan gagal saat Anda meneruskan parameter metode dengan referensi. Itu membutuhkan kompilator JIT untuk meneruskan pointer ke lokasi memori dari argumen yang diteruskan. Masalahnya, tidak ada, menetapkan nilai properti memerlukan pemanggilan metode penyetel. Metode yang dipanggil tidak dapat membedakan antara variabel yang diteruskan vs properti yang diteruskan dan karenanya tidak dapat mengetahui apakah pemanggilan metode diperlukan.
Perlu dicatat bahwa ini benar-benar berfungsi di VB.NET. Sebagai contoh:
Class Example
Public Property Prop As Integer
Public Sub Test(ByRef arg As Integer)
arg = 42
End Sub
Public Sub Run()
Test(Prop) '' No problem
End Sub
End Class
Kompiler VB.NET memecahkan masalah ini dengan secara otomatis menghasilkan kode ini untuk metode Jalankan, yang dinyatakan dalam C #:
int temp = Prop;
Test(ref temp);
Prop = temp;
Yang merupakan solusi yang dapat Anda gunakan juga. Tidak begitu yakin mengapa tim C # tidak menggunakan pendekatan yang sama. Mungkin karena mereka tidak ingin menyembunyikan panggilan pengambil dan penyetel yang berpotensi mahal. Atau perilaku yang sama sekali tidak dapat didiagnosis yang akan Anda dapatkan ketika penyetel memiliki efek samping yang mengubah nilai properti, mereka akan menghilang setelah penetapan. Perbedaan klasik antara C # dan VB.NET, C # adalah "tidak ada kejutan", VB.NET adalah "buatlah bekerja jika Anda bisa".