C# dilini öğrenmeye başladıysanız karşılaşacağınız en önemli konulardan birisi değer tipleri (value types) ve referans tipleri (reference types) olacaktır. İki tip arasındaki farkı anladığınızda yazılımınızın performansını ciddi derecede arttıracaksınız. Başlangıç seviyesinde ikisi arasındaki fark kafanızı karıştırabilir. Mantığını anladığınızda yazılımınızı hatasız bir şekilde geliştirebileceksiniz.
Değer Tipleri Nedir?
Değer tipleri olarak karşımıza çıkan doğrudan veriyi taşımaktadır. Yani, bir değer tipi tanımladığınızda o değişkenin tuttuğu veri stack bellekte saklanır.
- int
- double
- bool
- char
- struct
- enum
tipleri değer tipler olarak karşımıza çıkmaktadır.
Stack bellek kısa süreli verilerin saklandığı bir alandır. Burada her fonksiyon çağrısında yeni bir bellek bloğu ayrılır ve bu bloklar fonksiyon tamamlandığında otomatik olarak silinir. Değer tipleri burada saklanır, yani her değer tipi için bir bellek alanı ayrılır ve bu alan, işlem tamamlandığında temizlenir.
int a = 10; int b = a; // b artık 10 değerini taşır b = 20;
Console.WriteLine(a); // 10 Console.WriteLine(b); // 20
Bu örnekte a ve b birbirinden bağımsız bir şekilde hareket eder. b değişkenine a değişkeninin eşitlenmesi sonrasında b değişkeninin değiştirilmesi a değişkenini etkilemez. a değişkeni yine 10 olarak çıktı verir.
Referans Tipleri Nedir?
Referans tiplerinde değişken, verinin kendisini değil, verinin bulunduğu adresi (referansı) tutar. Veri ise heap bellekte saklanır.
- class
- string
- array (diziler)
- object
- interface
karşımıza referans tipler olarak çıkmaktadır.
Heap bellek (yığın dışı bellek), daha uzun süreli veri saklamaya yönelik kullanılır. Heap, dinamik bellek yönetimi sağlar ve veri burada saklanırken, değişken sadece verinin referansını taşır. Yani bir referans tipi oluşturduğunda, bellekteki veri bir adrese sahip olur ve bu adres stack’teki değişken tarafından tutulur.
class Ogrenci
{
public string Ad;
}
Ogrenci ogr1 = new Ogrenci();
ogr1.Ad = "Ali";
Ogrenci ogr2 = ogr1;
ogr2.Ad = "Ayşe";
Console.WriteLine(ogr1.Ad); // Ayşe
Console.WriteLine(ogr2.Ad); // Ayşe
Burada hem ogr1 hem de ogr2, aynı nesneye referans verir. Bu nedenle birinde yapılan değişiklik, diğerini de etkiler. İkisi de aynı referansa işaret ettiği için bellekteki veri değişince ikisine de aynı referanstaki aynı veri gelir.