Ini sebenarnya isu lama, bahkan om A.K. sudah mem-posting di tahun 2005, Reflection Sebagai Penjahat Perang Pelanggar OO. Saya sempat menaruh comment disana tapi mungkin tidak meng-elaborasinya… jadi saya mau bikin ini permanen di blog biar next time ada yg tanya bisa nyampe kesini via Google Live.
Anyway awalnya begini seminggu yg lalu…Di tempat saya consulting ada rekan yang iseng-iseng melemparkan quiz hari Jumat… kira-kira begini pertanyaannya:
Ada class A yg hanya berisi private field tanpa public mekanisme (public setter atau public method). Kemudian ada class B yang tidak inherit dari class A namun meng-agregat class A tadi. Bisakah class B ini mengubah private field class A tadi?
Kemudian saya memperhatikan ping-pong email yg intinya mengingatkan pada teori OOP tentang Encapsulation.
Kemudian akhirnya quiz ditutup dengan jawaban simple: TIDAK_BISA.
Karena saya orangnya suka melawan arus hehehe… maka saya gatal untuk memencet Reply-to-All dan mengetik opini berikut:
--- start of message ---
Bos, kalo di .NET ini BISA… coba jalankan source code berikut:
1: public static class ReflectionMagic
2: {
3: public static void ModifyPrivateMember(object instance,
4: string memberName,
5: object newValue)
6: {
7: Type t = instance.GetType();
8: System.Reflection.FieldInfo f = t.GetField(memberName,
9: BindingFlags.Instance
10: | BindingFlags.NonPublic
11: );
12: f.SetValue(instance, newValue);
13: }
14: }
15:
16: public class A
17: {
18: private string _password;
19: }
20:
21: [TestFixture]
22: public class B
23: {
24: [Test]
25: public void TestQuiz()
26: {
27: A newA = new A();
28:
29: ReflectionMagic.ModifyPrivateMember(newA, "_password", "I_Changed_Your_Password");
30: }
31: }
Ini screenshot hasil debugger, sebelum masuk ke kode ReflectionMagic:
Dan ini sesudah keluar dari kode ReflectionMagic:

--- end of message ---
Kegunaan readonly Reflection
Dan setelah email ini dikirim, mulailah muncul pertanyaan ttg apa gunanya punya private field kalo ternyata bisa “diakalin” juga… dan juga tentang kegunaan Reflection ini.
Hmm, menurut saya kemampuan inspeksi object secara runtime sangat powerful untuk pembuat utility/tools. Misal, Class View di Visual Studio ga bakal bisa jalan kalo nggak ada Reflection.
Secara personal, saya menggunakan Reflection untuk membuat VS2003 add-ins Refactor-Z dan UML Class Diagram Generator (separate note: yg kemudian tidak dikembangkan lebih lanjut gara2 di VS2005 udah ada fitur untuk “Surround Code with…” dan ada WhiteHorse atau klik kanan View Class Diagram).
Jadi reflection bagus untuk pembuat tools yg butuh menampilkan data-data object sewaktu runtime.
Kegunaan writeable Reflection
Tapi muncul pertanyaan, “lantas apa gunanya FieldInfo.SetValue ? Jika Anda hanya membuat tools untuk menampilkan data-data object sewaktu runtime kan bisa dengan FieldInfo.GetValue … buat apa MS ngasih SetValue?”
Well… kalo kasus ini saya belum pernah buat tool yg menggunakan SetValue sih… tapi biasanya fungsi ini digunakan untuk Data Transformation dan Mapping Tool (versi awal tool-tool ORM seperti Hibernate sepertinya menggunakan ini).
Cara Proteksi Private Field dari GetValue/SetValue
At the end of the day, pertanyaannya adalah “bisa nggak proteksi private fields class gw dari Reflection?”
Yo uwis kalo gitu, jawabannya bisa, dan tinggal tambahin kode ini sebelum kode namespace…
1: using System;
2: using System.Reflection ;
3: using System.Security.Permissions ;
4: using NUnit.Framework ;
5:
6: [assembly: ReflectionPermissionAttribute(
7: SecurityAction.RequestRefuse,
8: Unrestricted = true)]
9:
10: namespace ReflectionTests
11: {
12: public static class ReflectionMagic
13: {
14: ...
Hasilnya adalah seperti berikut… GetValue akan menghasilkan FieldAccessException:
Dan SetValue pun akan tidak berhasil mengubah private field kita:

Next time saya akan ngomongin tentang Code Signing deh… tidak berhubungan dgn Reflection, tapi masih dalam berhubungan dengan topik “membuktikan kode Anda belum pernah dimodifikasi orang lain” dan “membuktikan kode Anda benar-benar berasal dari Anda”.