Memahami Pass By Value Dan Pass By Reference Di C#

Pass by value vs pass by reference

Sebelum mempelajari apa itu “pass by value” dan “pass by reference“, coba perhatikan kode program di bawah ini.

static void Kuadrat(int x)
{
    x = x * x;
    Console.WriteLine(x);
}

static void Main(string[] args)
{
    int a = 3;
    Kuadrat(a);
    Console.WriteLine(a);
}

Kira-kira, berapa nilai variabel a dan x yang ditampilkan di layar konsol?

Kalau Anda menjawab variabel x bernilai 9, maka jawaban Anda benar. Tapi, apabila Anda menjawab variabel a juga bernilai 9, maka kali ini jawaban Anda… Salah! Yang benar, variabel a tetap bernilai 3.

Cukup banyak programmer pemula yang terjebak dalam situasti seperti di atas. Oleh karena itu, untuk menghindarinya, kita sebaiknya benar-benar memahami bagaimana memberikan argumen pada sebuah method agar menghasilkan keluaran yang diinginkan.

Pass By Value : Memberikan Salinan Nilai Variabel Ke Sebuah Method

Jadi, mengapa variabel a tetap bernilai 3?

Variabel a akan mendapatkan alokasi memori di stack. Lokasi memori tersebut akan menyimpan nilai dari variabel a, yaitu angka 3.

Lalu, pada saat memanggil method Kuadrat(), variabel a kita berikan sebagai argumen untuk method tersebut dengan harapan mendapatkan nilai kuadrat dari nilai yang disimpan di variabel a.

Perlu diperhatikan bahwa di dalam pemrograman C#, tanpa pengubah parameter apapun, setiap variabel yang digunakan sebagai argumen untuk sebuah method hanya akan memberikan salinan nilainya saja. Hal ini berlaku baik untuk variabel yang dideklarasikan dengan tipe data yang merupakan value type maupun reference type.

Karena tipe data variabel a merupakan value type, maka nilai yang tersimpan di lokasi memori variabel a adalah nilainya itu sendiri, yaitu angka 3. Oleh karena itu, nilai yang diberikan ke method Kuadrat() adalah salinan dari angka 3. 

Untuk lebih memahaminya, perhatikan gambar berikut ini.

Pass By Value

Jika Anda perhatikan, alamat memori di mana variabel a dan variabel x disimpan adalah dua alamat yang berbeda. Sehingga, apabila nilai variabel x berubah, nilai variabel a tidak akan terkena dampak.

Inilah yang disebut dengan Pass By Value. Yaitu, ketika nilai dari variabelnya saja yang diberikan sebagai argumen sebuah method.

Pass By Reference : Memberikan Alamat Memori Stack Sebuah Variabel Ke Sebuah Method

Lalu, bagaimana caranya agar variabel a bernilai 9?

Jawabannya, Anda harus memberi tau lokasi memori di mana variabel a disimpan. Dengan begitu, method Kuadrat() akan memiliki akses terhadap variabel a.

Caranya adalah dengan menambahkan kata kunci ref pada setiap parameter yang ingin mendapatkan informasi lokasi memori dari argumennya.

Kode program di atas bisa kita tulis ulang seperti berikut ini.

static void Kuadrat(ref int x)
{
    x = x * x;
    Console.WriteLine(x);
}

static void Main(string[] args)
{
    int a = 3;
    Kuadrat(ref a);
    Console.WriteLine(a);
}

Perlu diperhatikan bahwa Anda juga perlu menambahkan kata kunci ref di depan argumen pada saat memanggil method tersebut.

Gambar di bawah ini menjelaskan bagaimana kode program di atas dapat menghasilkan angka 9. Sesuai dengan ekspektasi Anda.

Pass By Reference

Kali ini, method Kuadrat() mendapatkan referensi atau pointer ke alamat lokasi variable a yang digunakan sebagai argumen untuk method tersebut. Sehingga, method tersebut kini memiliki akses terhadap variabel a.

Menggunakan referensi ke variabel a untuk melakukan operasi di method Kuadrat(),  sebenarnya adalah operasi terhadap variabel a itu sendiri. Sehingga operasi tersebut akan mengubah nilai dari variabel a.

Inilah yang disebut dengan Pass By Reference. Yaitu, ketika referensi atau pointer ke alamat lokasi memori sebuah variabel diberikan sebagai argumen sebuah method.

Memberikan Tipe Referensi Sebagai Argumen. Pass By Reference Atau Pass By Value?

Jawabannya: Pass By Value!

Sebelumnya sudah disebutkan bahwa di dalam pemrograman C#, tanpa pengubah parameter, setiap variabel yang digunakan sebagai argumen untuk sebuah method hanya akan memberikan salinan nilainya saja. Hal ini berlaku baik untuk variabel yang dideklarasikan dengan tipe data yang merupakan value type maupun reference type.

Perhatikan kode program di bawah ini.

class MyClass
{
    public int x;
}

class Program
{
    static void Kuadrat(MyClass mcObj)
    {
        mcObj.x = mcObj.x * mcObj.x;
    }

    static void Main(string[] args)
    {
        MyClass mc = new MyClass();

        mc.x = 5;

        Kuadrat(mc);

        Console.WriteLine(mc.x);

        Console.ReadLine();
    }
}

Kode program di atas akan menghasilkan keluaran sesuai dengan ekspektasi, yaitu angka 25.

Nilai Keluaran Sesuai Ekpektasi

Apabila kita memberikan sebuah instance dari class, yaitu objek mc, sebagai argumen untuk method Kuadrat(), ternyata tanpa menggunakan kata kunci ref, kita bisa mendapatkan nilai keluaran yang sesuai dengan ekspektasi.

Jawaban saya tadi salah? Tidak.

Coba perhatikan gambar di bawah ini.

Memberikan Objek Sebagai Argumen

Pada saat memanggil method Kuadrat(), apakah yang diberikan sebagai argumen untuk method tersebut adalah alamat variabel mc (0x06A8EED4) atau nilai dari variabel mc (0x02B4754C)?

Nilainya, bukan?

Mengapa nilai keluarannya bisa 25? Karena operasi pada method Kuadrat() dilakukan di memori heap di mana objek mc sebenarnya di simpan. Variabel mcObj pada method Kuadrat() menunjuk alamat memori heap yang sama dengan yang ditunjuk oleh variabel mc. Operasi terhadap variabel mcObj merubah nilai dari objek mc di heap. Bukan merubah nilai dari variabel mc di stack.

Menggunakan kata kunci ref artinya mendapatkan akses terhadap suatu variabel yang digunakan sebagai argumen untuk sebuah method. Artinya, method tersebut mendapat akses ke lokasi variabel tersebut di stack. Sehingga, ketika method tersebut melakukan operasi menggunakan referensi ke alamat variabel tadi, nilai dari variabelnya di stack juga akan berubah.

Apakah nilai dari variabel mc di stack berubah? Tidak. Karena yang diberikan ke method Kuadrat() adalah salinan dari nilai variabel mc. Kebetulan variabel mc ini berisi sebuah referensi / pointer ke sebuah alamat memori di heap.

Sudah mengerti mengapa jawaban saya adalah Pass By Value?

Kesimpulan

Pass By Value adalah ketika kita memberikan salinan nilai sebuah variabel sebagai argumen untuk sebuah method. Karena yang diberikan hanya salinan nilainya saja, maka nilai variabel tersebut tidak akan berubah meskipun di dalam method tersebut nilainya berubah karena digunakan untuk melakukan berbagai operasi.

Pass By Reference adalah ketika kita memberikan referensi / pointer ke alamat lokasi variabel yang digunakan sebagai argumen untuk sebuah method. Memberikan referensi ke alamat variabel berarti memberi akses terhadap variabel tersebut. Setiap operasi yang menggunakan referensi tersebut akan merubah nilai variabelnya di stack. Pass By Reference bisa dilakukan dengan menambahkan kata kunci ref.

Apabila Anda mempunyai pertanyaan seputar materi di tulisan ini, silahkan tinggalkan pertanyaan Anda di kolom komentar.

Selamat belajar!

Mendapat Manfaat Dari Tulisan Ini? Bantu Bagikan Ya...
Share on facebook
Facebook
Share on twitter
Twitter
Share on linkedin
LinkedIn
Share on whatsapp
WhatsApp
Tinggalkan Balasan

Close Menu