Struct Yapısı
Sınıflar gibi, struct yapıları veri
ve fonksiyon üyeleri içeren veri yapılarıdır. Sınıflardan farklı olarak, struct
yapısı değer tipidir ve heap bölge tahsisi gerektirmez. Bir struct değişkeni,
direkt olarak struct’ın verisini tutar. Oysa sınıf tipinde bir değişken,
dinamik olarak ayrılmış nesneye referans tutar. Struct yapısı, kullanıcı
tanımlı kalıtımı desteklemez ve tüm struct yapıları dolaylı olarak object
tipinden kalıtım alır.
! Struct
yapılarının heap bölge tahsisi gerektirmemesi, bu yapıların hiçbir zaman bunu
yapmadıkları anlamına gelmez.
Bu yapılar özellikle küçük veri
yapıları kullanımında kullanışlı olurlar. Karmaşık sayılar ve koordinat
sisteminde noktalar struct yapılarına iyi örneklerdir. Bir yapıda sınıf yerine
struct kullanımı, bellek tahsis etmede ve programınızın performansında büyük
farklılıklar yaratabilir.
Örnek;
Aşağıdaki program 100 nokta
oluşturan bir programdır. Sınıf yapısı ile kullandığımızda 101 adet farklı
nesne – 1 adet dizi için, 100 adet te dizi üyeleri için – oluşturulur:
using System;
class Nokta
{
public int x, y;
public Nokta(int x, int y)
{
this.x = x;
this.y = y;
}
}
class Test
{
static void Main()
{
Nokta[] noktalar = new Nokta[100];
for (int i = 0; i < 100; i++)
noktalar[i] = new Nokta(i, i);
}
}
|
Alternatif olarak Nokta yapısını
struct yapabiliriz.
struct Nokta
{
public int x, y;
public Nokta(int x, int y)
{
this.x = x;
this.y = y;
}
}
|
Burada sadece 1 nesne yaratılır – 1
adet dizi için – ve Nokta örnekleri dizi içerisinde saklanırlar.
! Struct yapısının performans
açısından sağladığı faydayı “Her zaman struct kullanın” şeklinde algılamak
yanlış olur. Tabi ki bazı senaryolarda struct yapısına bellek ayırmak ve
bellekten almak daha az zaman alır fakat her struct ataması bilindiği gibi
değer kopyalamasıdır (value copy). Bu her zaman referans kopyalamasından daha
fazla zaman alır.
Struct yapıcıları new
operatörü ile çağrılırlar fakat bu demek değildir ki belirli bir bellek
ayrılmıştır. Nesnenin veya referansının dinamik olarak bellek ayrımı yerine,
bir struct yapıcısı basitçe struct değerinin kendisini döndürür (genellikle
yığının geçici bölgesinde) ve bu değer gereli olduğunda kopyalanır.
Sınıflarda, iki farklı değişken aynı
nesneye referans gösterebilir ve bu şekilde bir değer üzerindeki işlemler aynı
nesneyi referans eden diğer değişkeni etkileyebilir. Struct yapılarında, her
değişken kendi verisinin kopyasını tutar ve bir değişkenin diğerini etkilemesi
imkansızdır. Örneğin aşağıdaki kodu inceleyelim;
Nokta a = new Nokta(10, 10);
Nokta b = a;
a.x = 20;
Console.WriteLine(b.x);
|
Eğer buradaki Nokta örneği
bir sınıf (class) ise, sonucumuz 20 olur çünkü a ve b aynı nesneye referans
gösterirler. Eğer Nokta örneği bir struct ise, sonucumuz 10 olur çünkü
ikinci satırdaki atama işlemi değer olarak a’daki değerleri b’ye kopyalar ve bu
kopyalama 3. satırdaki a.x atamasını etkilemez.
Bu örnekte struct kullanımının 2
noktasının farkına vardık. Birincisi, tüm struct yapısını kopyalamak bir nesne
referansını kopyalamaktan daha az verimli. Böylece atama yapma ve değer
parametresi geçirme struct yapılarında referans tiplerine göre daha maliyetli
olabilir. İkincisi, ref ve out parametreleri dışında, struct yapısına referans
oluşturma imkansızdır.
Yorum Gönder Blogger Facebook