Halo! Selamat datang kembali di “Seri Belajar Dasar Pemrograman Bahasa C#“. Pada materi-materi sebelumnya, kita sudah cukup sering menyinggung tentang value type dan reference type. Sampai saat ini kita sudah memahami bahwa value type dialokasikan ke memori stack, sedangkan reference type dialokasikan ke memori heap. Namun, apa sebenarnya efek dari memilih menggunakan value type atau reference type pada program yang kita buat?
Pada materi kali ini, kita akan mencoba bereksperimen dengan tipe struct (value type) dan tipe class (reference type) untuk melihat apa efek dari memilih menggunakan tipe struct dibanding menggunakan tipe class untuk membuat blueprint dari sebuah objek. Dengan demikian, kita akan lebih mudah memahami perbedaan antara value type dan reference type.
Mendefinisikan Class dan Struct
Sebelum memulai materi kita kali ini, kita terlebih dahulu perlu mendefinisikan sebuah struct dengan nama Coordinate
dan sebuah class dengan nama CoordinateRefType
.
Tipe struct:
public struct Coordinate
{
public int X;
public int Y;
public Coordinate(int x, int y)
{
X = x;
Y = y;
}
public void ShowCoordinate()
{
Console.WriteLine("nilai koordinat: X = {0}, Y = {1}", X, Y);
}
}
Tipe class:
public class CoordinateRefType
{
public int X;
public int Y;
public CoordinateRefType(int x, int y)
{
X = x;
Y = y;
}
public void ShowCoordinate()
{
Console.WriteLine("nilai koordinat: X = {0}, Y = {1}", X, Y);
}
}
Jika kita perhatikan, definisi class dan struct di atas sekilas nampak identik karena keduanya memiliki member (field dan method) yang sama persis. Perbedaannya hanya terletak pada penggunaan kata kunci class
dan struct
serta identifiernya saja (Coordinate
dan CoordinateRefType
).
Menyalin Class Dan Struct
Untuk melihat perbedaan mendasar antara tipe struct yang dialokasikan ke memori stack dengan tipe class yang dialokasikan ke memori heap, kita akan mencoba menyalin nilai variable dari tipe struct dan juga tipe class.
Dengan begitu, kita bisa melihat apa efek dari mengganti nilai aslinya terhadap nilai salinannya.
Menyalin objek dari tipe struct
Pertama-tama, kita akan membuat sebuah objek dari tipe struct Coordinate
dengan cara seperti di bawah ini.
Coordinate p1 = new Coordinate(10, 10);
Tentu saja karena tipe struct Coordinate
adalah dari value type, maka objek p1
akan dialokasikan ke memori stack.
Selanjutnya kita akan mencoba menyalin p1
ke sebuah variabel yang lain dari tipe struct yang sama, yaitu Coordinate
, katakanlah p2
.
Coordinate p2 = p1;
Lalu, tampilkan nilai koordinat X dan Y dari masing-masing objek p1
dan p2
tersebut dengan memanggil method ShowCoordinate()
seperti di bawah ini.
p1.ShowCoordinate();
p2.ShowCoordinate();
Jika dijalankan, program kita akan menampilkan keluaran seperti berikut ini.
nilai koordinat: X = 10, Y = 10 // p1
nilai koordinat: X = 10, Y = 10 // p2
Sekarang, kita akan mencoba mengganti nilai X pada objek p1
dengan angka 100.
p1.X = 100;
Setelah itu, kita tampilkan lagi nilai koordinat X dan Y dari masing-masing objek p1
dan p2
tersebut dengan memanggil kembali method ShowCoordinate()
.
p1.ShowCoordinate();
p2.ShowCoordinate();
Kali ini keluarannya akan seperti di bawah ini.
nilai koordinat: X = 100, Y = 10 // p1
nilai koordinat: X = 10, Y = 10 // p2
Apa yang bisa kita lihat dari eksperimen kali ini?
Ya, kita bisa melihat bahwa mengganti nilai X pada objek p1
(p1.X
) tidak akan memberikan efek apa-apa terhadap nilai X pada objek p2
(p2.X
).
Mengapa?
Karena tipe struct adalah dari value type, maka setiap member dari objek p1
akan mendapat alokasi memori di stack. Jadi, baik field X
(p1.X
) dan field Y
(p1.Y
), keduanya akan dialokasikan di stack.
Pada saat menyalin p1
ke p2
, nilai dari p1.X
dan p1.Y
masing-masing akan disalin ke lokasi memori yang lain di stack sebagai p2.X
dan p2.Y
. Dengan demikian, baik p2.X
maupun p2.Y
hanya mendapatkan nilai dari p1.X
dan p1.Y
saja.

Jika kita perhatikan gambar di atas, objek p1
dan p2
adalah dua buah objek yang berbeda. Dengan kata lain, baik p1
maupun p2
menempati alokasi memori yang berbeda di stack. Oleh karena itu, mengganti nilai p1.X
hanya akan mengubah nilai X pada objek p1
, sementara nilai X pada objek salinannya tidak akan terpengaruh.
Menyalin objek dari tipe class
Sekarang, kita akan bereksperimen dengan tipe class yang merupakan reference type.
Pertama-tama, buat sebuah objek dari tipe class CoordinateRefType
seperti di bawah ini.
CoordinateRefType p3 = new CoordinateRefType(10, 10);
Lalu salin objek p3
ke objek dari tipe yang sama, katakanlah p4
.
CoordinateRefType p4 = p3;
Tampilkan nilai koordinat dari p3
dan p4
.
p3.ShowCoordinate();
p4.ShowCoordinate();
Jika dijalankan, kita akan mendapatkan keluaran seperti di bawah ini.
nilai koordinat: X = 10, Y = 10
nilai koordinat: X = 10, Y = 10
Sejauh ini, kita mendapatkan keluaran yang sama persis dengan ketika menggunakan tipe struct.
Tapi, sekarang coba ganti nilai X pada objek p3
dengan angka 100.
p3.X = 100;
Tampilkan kembali nilai koordinat p3
dan p4
.
p3.ShowCoordinate();
p4.ShowCoordinate();
kali ini, kita akan mendapatkan keluaran seperti di bawah ini.
nilai koordinat: X = 100, Y = 10
nilai koordinat: X = 100, Y = 10
Dari keluaran yang kita dapatkan, jelas terlihat bahwa apabila kita mengganti nilai X pada objek p3
, nilai X pada objek p4
juga ikut berubah.
Begitu pula jika kita mengganti nilai X pada objek p4
, nilai X pada objek p3
juga akan ikut berubah.
Mengapa?
Karena tipe class adalah dari reference type, variabel p3
hanya menyimpan referensi alamat di mana objek p3
sebenarnya disimpan di memori heap.
Katakanlah objek p3
dialokasikan di memori heap pada alamat x200. Maka nilai variabel p3
adalah alamat dari objek p3
, yaitu x200. Apabila nilai variabel p3
disalin ke variabel p4
, maka baik p3
maupun p4
akan menunjuk pada sebuah objek yang dialokasikan di alamat x200. Artinya, baik p3
maupun p4
, kini menunjuk pada satu buah objek yang sama.

Dengan demikian, mengganti nilai p3.X
juga akan mengubah nilai p4.X
karena p3
dan p4
sebenarnya memiliki referensi ke satu buah objek yang sama.
Penutup
Pada materi kali ini kita telah mempelajari perbedaan antara menggunakan value type dan reference type di C#.
Dengan lebih memahami efek menggunakan value type atau reference type, tentunya kita akan lebih cermat ketika harus memilih antara menggunakan tipe class atau tipe struct untuk membuat blueprint sebuah objek.
Jika Anda merasa kesulitan dalam memahami materi tipe data dan variabel, jangan menyerah! Tulis kesulitan atau pertanyaan Anda di kolom komentar, saya akan membantu.
Selamat belajar!