Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C#’ta Struct Yapıları ve Kullanım Durumları

Merhaba,

Programlama dillerinde en mühim OOP(Object Oriented Programing) yapılarından olan class yapısına göre daha basit düzeyde işlemler gerçekleştirmemizi sağlayan ve belirli bir takım kısıtlamaları yanında barındıran struct yapısını C# diline özel ele alacağız.

Şimdi düşünün ki, bir yapı oluşturacaksınız ve bu yapı birbirleriyle ilişkili verileri barındıracaktır. Haliyle bunu bir class olarak belirleyebilir ve o classtan üretilen nesne üzerinde işlemlerimizi icra edebiliriz. Amma velakin bu yapımız class kadar kompleks işlemler için tasarlanmış bir yapı gerektirmiyorsa ve tutulacak verileri enkapsüle etmek yetiyorsa işte bu tarz durumlarda struct yapısını tercih edebiliriz.

Unutmayınız ki, classlar bir Referans Tipli(Reference Types) özellik gösterirken struct yapıları bir Değer Tipli(Value Types) değişken özelliği göstermektedir.

Yani anlayacağınız “int” gibi, “bool” gibi değer tipli bir değişken oluşturmak istiyorsanız struct yapısını tercih edebilirsiniz.

Bu demek oluyor ki, gerçekleştireceğimiz işlevselliğin yapısal olarak bir nesne yahut değer tipli bir değişken yapısında gerçekleştirilmesini tercih edebilir ve birazdan bahsedeceğim olumlu olumsuz yanlarıda hesaba katarak projenizde performansı daha maliyetli bir hale getirebilirsiniz.

Şimdi struct yapısını C# perspektifinden adım adım değerlendirelim;

  • Yazımızın yukarıdaki satırlarında da bahsettiğimiz gibi struct C#’ta value type yaratabileceğimiz yapıdır.
  • struct yapıları, herhangi bir struct yahut class’tan kalıtım alamazlar.
    C#'ta Struct Yapıları ve Kullanım Durumları C#'ta Struct Yapıları ve Kullanım Durumları

    Benzer şekilde bir class yapısıda struct yapısından miras alamamaktadır.

  • struct yapıları, interface yapılarını uygulayabilmektedirler.
        struct MyStruct1 : IInterface
        {
            int x;
            bool y;
            public void A()
            {
                throw new NotImplementedException();
            }
            public void B(bool c)
            {
                throw new NotImplementedException();
            }
        }
    
        interface IInterface
        {
            void A();
            void B(bool c);
        }
    
  • struct yapılar new keywordüyle örneklendirilebilmektedir. Burada iki durum söz konusudur.
    1. Eğer new operatörüyle örneklendirirsek ne olur?
      Bildiğiniz gibi new operatörü classlarda kullanıldığı zaman ilgili classtan bir nesne talep edilmekte ve üretilen nesne belleğin Heap kısmında muhafaza edilmektedir. Ee söz gelimi struct yapısında da new operatörünü kullanırsak eğer evet ilgili yapıdan bir nesne üretilecektir ama struct bir değer tipli değişken yapısında olduğundan dolayı o nesne belleğin Stack kısmında muhafaza edilecektir.

      Bu yapıya kadar oluşturduğumuz tüm nesnelerin Heap kısmında olduğunu söylemiştik. Halbuki Stack kısmında struct yapısında nesneleri tutabilmekteyiz.

      Ayriyetten struct içerisindeki fieldlara default değerleri atanmış olacaktır.

          public partial class Form1 : Form
          {
              public Form1()
              {
                  InitializeComponent();
              }
      
              private void Form1_Load(object sender, EventArgs e)
              {
                  MyStruct ms = new MyStruct();
                  MessageBox.Show(ms.x + " " + ms.y + " " + ms.z);
              }
          }
      
          struct MyStruct
          {
              public int x;
              public bool y;
              public string z;
          }
      

      Ekran çıktısı aşağıdadır.
      C#'ta Struct Yapıları ve Kullanım Durumları

    2. Eğer new operatörü kullanmazsak ne olur?
      Haliyle classlardaki gibi nesne mecburiyeti yoktur. Yani new operatörü ile struct yapıdan bir nesne üretmeden de o struct’ı kullanabilmekteyiz.
      C#'ta Struct Yapıları ve Kullanım Durumları
      Yukarıda da gördüğünüz gibi nesnesiz structları kullanabilmekteyiz kullanmasına ama içerisindeki verilerin ilk değerleri atanmayacağından dolayı hata alınacaktır.

      İşte böyle bir durumda ilk değerleri atayarak kullanmak gerekecektir.

                  MyStruct ms;
                  ms.x = 3;
                  ms.y = true;
                  ms.z = "abc";
                  MessageBox.Show(ms.x + " " + ms.y + " " + ms.z);
      

      Anlayacağınız class yapıları new keywordü ile belleğe fiziksel olarak çıkabilmekte ve kullanılabilmektedir. Aksi taktirde belleğe çıkamamaktadırlar. Struct’larda ise new ile belleğe çıkma zorunluluğu yoktur lakin içerisindeki elemanların ilk değerleri mecburi verilmek zorundadır.

  • struct yapılar içerilerinde metod, property veya field barındabilirler.
        struct MyStruct
        {
            public int x;
            public bool y;
            public string z { get; set; }
    
            public double Islem()
            {
                if (y)
                {
                    return x * int.Parse(z);
                }
    
                return -1;
            }
        }
    

    Haliyle bu elemanlardan metodları kullanabilmek için struct değişkenine new operatörüyle bir nesne bağlama zorunluluğumuz yoktur. Ama property yapılarını kullanabilmek için struct’tan bir nesneye ihtiyacımız vardır.

            private void Form1_Load(object sender, EventArgs e)
            {
                MyStruct ms = new MyStruct();
                ms.x = 3;
                ms.y = true;
                ms.z = "3";
                MessageBox.Show(ms.x + " " + ms.y + " " + ms.z + " " + ms.Islem());
            }
    
  • struct yapılar içlerinde static alanlar barındırabilirler.
        struct MyStruct
        {
            public int x;
    
            static public double Islem()
            {
                return -1;
            }
        }
    

    ve bu static yapılara normal bildiğiniz yapı ismi üzerinden .(nokta) diyerek ulaşabilmekteyiz.

                MyStruct.Islem().ToString();
    
  • Ve son olarak struct yapılar içerisinde class, class içerisinde de struct yapılar tanımlanabilir.
    C#'ta Struct Yapıları ve Kullanım Durumları C#'ta Struct Yapıları ve Kullanım Durumları

Evet, gördüğünüz gibi struct dediğimiz aslen yapısal ve içerik(implicit) olarak bir sealed class‘tır diyebiliriz. Bunun yanında daha hafif(lightweight) bir class yapısı olduğu söylenebilir. İçeriğimizden de anlaşılacağına göre Tip Tanımlama(Type Definition) yaparken kullanabiliriz.

İçerikte bahsedildiği gibi referans değil, değer tipli bir yapı göstermesinin sebebini aşağıdaki örnekten de anlayabiliriz.
C#'ta Struct Yapıları ve Kullanım Durumları
Burada dikkat ederseniz eğer ms.x ve ms.y değişmeyeceğinden dolayı bir Deep Copy söz konusudur. Eğer referans tipli yapılar olsalardı aşağıdaki gibi bir sonuç elde edilecekti ve Shallow Copy söz konusu olacaktı.

C#'ta Struct Yapıları ve Kullanım Durumları

Gördüğünüz gibi iki referansta aynı nesneyi işaret ettiğinden dolayı referanslar üzerindeki field değerleri doğal olarak aynı sonucu vermekte yani mc.x ve mc.y değişkenlik göstermektedir.

Son olarak struct yapılarıyla ilgili uç bir noktaya daha değinip içeriğimizi sonlandıralım.

struct yapılar, kendilerini this keywordünü kullanarak değiştirebilen yapılardır.

Örneğin;
C#'ta Struct Yapıları ve Kullanım Durumları

Aslında bu tarz bir işleme class yapısı izin vermediğinden dolayı ilginç bir özelliktir.
C#'ta Struct Yapıları ve Kullanım Durumları

Güzel ve eğlenceli bir konununda sonuna gelmiş bulunmaktayız.
Okuduğunuz için hepinize teşekkür ederim…
Sonraki yazılarımda görüşmek üzere diyelim… 🙂
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

5 Cevaplar

  1. Aydoğan dedi ki:

    Vaybe

    Struct ile ilgili aklımda oluşan tüm sorulara cevap oldu bu kaynak.

    Teşekkürler

  2. Levent dedi ki:

    Performans konusunda olumlu ve olumsuz yönlerini belirtmemişsiniz.
    Ayrıca fonksiyonel programlamada struct kullanılmasının sebebini biliyor musunuz?
    Fonksiyonel programlamada Performans ve diğer konularda artıları ve eksileri neler olabilir?

    • Gençay dedi ki:

      Yani bir eleştiri mi bu? Yoksa bir merama dayalı sual mi var? Pek anlayamadım…

      Evet, makalede eksiklikler olabilir. Bunu eleştiri olarak kabul ediyorum. Fonksiyonel programlamada struct kullanılmasının nedenini de bilmiyor, performans ve diğer konular hakkında da herhangi bir fikir barındırmıyorum. Siz biliyorsanız lütfen aydınlatır mısınız?

  3. orkun dedi ki:

    güzel bi yazı olmuş teşekkürler…

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir