C# Değer Tip ve Referans Tip (Value Type - Reference Type)
Programcı olarak bilmemiz gereken kavramlardan olan değer tip ve referans tip nedir, onlardan kısaca bahsedeceğiz.
Öncelikle eğer bilmiyorsanız, programlama yaparken kod kullandığımız yapılar ve veriler, stack ve heap adında iki tane hafıza bölgesinde depolanmaktadır. Stack hafıza bölgesi isminden anlaşılacağı üzere aslında stack veri yapısının çalıştığı gibi çalışan bir çeşit hafıza kullanımı sağlayan hafıza bölgesidir. Stack hafıza kullanımında her şey bellidir diyebiliriz, belirli bir adres kullanımı vardır. Stack üzerinde depolanan verilerin hafızanın neresinde konuşlanacağını az çok bilebiliriz. Örneğin main fonksiyonumuz stack üzerinde yer alan ilk frame'dir. Bu frame'leri çerçeve olarak düşünelim. Her fonksiyon çalışmasında bu çalışma sonucu kadar bir fonksiyon çerçevesi stack hafızasına eklenecektir. Zaten stack overflow gibi oldukça popüler kavram da buradan gelmektedir. Sonsuz bir recursive fonksiyon kullanımına olanak verirsek sonuç olarak stack overflow'a izin vermiş olacağız yani stack taşması. Çünkü stack hafıza kullanımımız sınırlıdır. Stack hafızası LIFO açılımı Last-in, First-out mantığına göre çalışır yani son giren, ilk çıkar ya da ilk giren, son çıkar olarak da tarif edebiliriz. int, double, float, decimal gibi standart veri tipleri tanımlanmış değişkenler ve değerler value type(değer tip) olarak görülür ve stack bölgesinde yer alırlar.
Referans tip tanımlamalarda değerler stack yerine heap bölgesinde yer alınmaktadır. Depolanmak üzere yer ayrılacak olan bu değer veya değerler bütününe göre uygun şekilde bir boş hafıza bölümü bulunur ve o noktanın başlangıcını gösteren adres değişken içinde saklanır. Bu adres stack bölümünde depolanmaktadır. ve heap bölgesindeki değer veya değerlerin başlangıç noktasıdır. Yani heap'te yer alan o verilere ulaşabilmemizin tek yolu o adrestir veyahut buna referans da diyebiliriz.
Peki neden böyle bir şeye gerek var? Öncelikle stack bölümünde işlemler daha az maliyetle oluyor, bu noktada heap'e göre çok daha avantajlı fakat dezavantajı sabit yani değişmez olması. Örneğin sabit bir dizi yapısına run-time anında müdahale etmemiz mümkün değil. Program sonlanana kadar ne eleman silebilir ne de eleman arttırımında bulunabiliriz. Ancak dinamik bellek kullanımında yani heap kullanımında böyle bir dert yoktur, dizi içinde sonrasında değişiklik yapabiliriz. Yine aynı şekilde class yapıları, interface, diğer veri yapıları ve dahası için de bu durum geçerlidir. Yani bunlar referans tiplerdir. Ancak heap kullanımı stack bölgesine nazaran daha riskli ve maliyetlidir. Çünkü her program çalışmasında heap kullanımı farklılık gösterecektir ve hafızada nereyi kullanabilirse orayı kullanacaktır. Riskli olmasının sebebi ise hafızada alınan yerin iade edilmemesinden doğacak sonuçlardır. Bilinen en büyük sorunlardan birisi memory leak'e sebep olabilir. Bu nedenle ne kadar yer ayrıldıysa, o kısımla işimiz bittiği anda o kısmı hafızaya geri iade etmeliyiz. Normalde bu iade işlemleri C ve C++ gibi programlama dillerinde elle yapılıyor ancak C#, Java gibi dillerde Garbage Collector denen çöp toplayıcı bu işlemi programcının yerine yapmaktadır, tabi run-time olarak, o sebeple bu gibi riskler C# için son derece düşük sayılabilir ama elbette istisna durumlar vardır.
Hiç yorum yok: