C# 6.0 – Primary Constructors

   C# 6 makale serisinde hızla ilerlemeye devam ederken sıra geldi Primary Constructers konusuna değinmeye. Önceki  konuları incelerken, özellikle de Pattern Matching (desen eşleştirme) konusunda eminim ki fark etmişsinizdir; C#’ta giderek artan bir şekilde fonksiyonel programlama etkileri hissedilmekte. Özellikle F# dilinin bu etkide önemli bir payı olduğunu söylememiz mümkün. Kuşkusuz ki; Primary Constructers’da bu etkilerle C# diline kazandırılan yeniliklerden birisi.

   Bunun benden sık sık duyduğunuza eminim; C# dili giderek bize daha az kod yazdırmayı hedefliyor. Dolayısıyla zaman içinde kazandığı pek çok yenilik aslında bizim tekrar tekrar yaptığımız işlemlerin daha basitleştirilmesinden ibaret. Başka bir değişle bu yeniliklerin azımsanamayacak kadar önemli bir bir bölümü dil söz diziminde yapılan değişiklikler ile bu değişikliklerin derleyici tarafından desteklenmesidir. Auto-Property’ler bunun en güzel örneklerinden birisidir. Hatta bir önceki makalemde paylaştığım Auto-Property iyileştirmeleri de aynı şekilde. Bu bakış açısıyla yeniliklere yaklaştığınızda eminim ki dile daha hakim bir şekilde ilerleyebilirsiniz. Primary Constructers’da bundan farklı bir durum değil aslında.

   Ok. Bu girişten sonra artık konumuza başlayalım. C# dil geliştiricileri pek çok uygulama üzerinde yaptıkları inceleme ve aldıkları geri bildirimler neticesinde yazılımcıların bazı kod desenlerini çok sık tekrar ettiklerini görmüşlerdir. Bu desenlerin kullanımıyla ilgili dile eklenecek basit söz dizimsel iyileştirmeler ile önemli bir zaman kazanılacağı ortadadır. Bu yaklaşımla aşağıdaki kodu inceleyelim;

public class Ogrenci {
    private string adi;
    private string soyadi;
     
    public string Adi { get { return adi; } }
    public string Soyadi { get { return soyadi; }  } 
     
    public Ogrenci(string adi, string soyadi){
        this.adi = adi;
        this.soyadi = soyadi;
    }
}

   Eminim ki pek çok kez buna benzer kod yazdınız.

  C# 6 ile birlikte gelen Auto-Property’lerdeki iyileştirmeler arasında paylaştığım getter-only auto-property’leri hatırlarsanız. Yukarıdaki kod artık aşağıdaki şekilde sadeleştirilebilir duruma geldi;

public class Ogrenci {
     public string Adi { get; }
     public string Soyadi { get;  } 
     
     public Ogrenci(string adi, string soyadi){
        Adi = adi;
        Soyadi = soyadi;
     }
}

   Bu yenilik ile birlikte bir adımda kurtulmuş olduk. Salt-okunur olmasını istediğimiz property’ler için artık arka-plan değişkenleri tanımlamaya ihtiyacımız kalmadı. Diğer yandan hala çok sık tekrarladığımız bir kod bloğu bulunuyor; bu auto-property’lerin dışarıdan alınan değişkenlerle ilklendirilmesi. Tam da bu noktada, C# 6 ile birlikte gelen primary constructers özelliği devreye girmekte. Dil geliştiriciler du gibi kod geliştirmesini kolaylaştırma adına aynı kodun aşağıdaki söz dizimi ile yazılabilmesine olanak vermişlerdir;

public class Ogrenci(string adi, string soyadi) {
     public string Adi { get; } = adi;
     public string Soyadi { get;  } = soyadi;
}

   Paylaştığım ilk örnekle kıyasladığımızda önemli bir kod hammallığından kurtulduğumuz rahatlıkla görülecektir. Derleyiciden çıkan kod incelendiğinde ise ilk yaklaşımdaki kod ile çok farklı olmadığı görülebilir.

   Primary Constructers ile birlikte C# diline gelen bu yeni söz dizim kurallarını incelediğimizde ise daha önceden standart constructer olarak kullandığımız imzanın sınıf tanımına taşınarak sadeleştirildiğini görebiliriz. Aynı şekilde constructer’ımız içindeki atama işlemleri de kaldırılarak constructer için verdiğimiz parametrelerden yola çıkılarak oluşturulan arka-plan değişkenlerine otomatik atama yapılmakta.

  Örneğimize dikkat edecek olursanız getter-only auto-property’lerde primary constructer değişkenlerini kullanabildiğimizi görebilirsiniz. Bu kullanımda this ile bu değişkenlere referans verilmediği de dikkatinizi çekmiştir.

  C# söz dizimindeki bu değişimle birlikte ilk örneğimizdekine benzer kullanımlar önemli ölçüde sadeleşecektir. Bununla birlikte kimi kullanımlarda constructer içindeki bu basit atama işlemleri yanında ek iş mantıkları da işletilebilmektedir. Primary Constructer için yapılan çalışmalarda bu gibi senaryolarda göz önüne alınarak C# söz dizimine ufak bir ekleme daha yapılmış. Buna göre Primary Constructer içerisinde gerçekleştirilmesini istediğiniz ek iş mantıkları için, aşağıda örneklendiği şekilde, sınıf tanımının hemen içerisinde süslü parantezlerle belirlediğiniz bir alanı kullanabilirsiniz;

public class Ogrenci(string adi, string soyadi) {
    {
        if (adi == null) throw new ArgumentNullException("adi");
        if (soyadi == null) throw new ArgumentNullException("soyadi");
    } 
    
     public string Adi { get; } = adi;
     public string Soyadi { get;  } = soyadi;
}

   Örneğimizde primary constructer için geçilen parametrelerin null durumları kontrol edilmekte.

   Kimi senaryolarda, daha kolay ve esnek kullanımlar için farklı imzalara sahip constructer’lar oluşturmak isteyebilirsiniz. En nihayetinde Primarry Constructer’lar da derlendiğinde benzer kodlar üretildiği için bu kullanım Primary Constructer’lar için de geçerli; ama ufak bir farkla… Dil geliştiriciler, Primary Constuctors tasarımını yaparken bu gibi senaryolarda primary constructor dışındaki tüm constructor’ların primary constructor’ı çağırmalarını şart koşmuşlardır. Yukarıda örneklediğim kullanımlar göz önüne alındığında bu kuralın primary constructor parametrelerinin doğru şekilde ilklendirildiğini garanti altına almak için olduğu rahatlıkla görülecektir. Primary Constructor’ın çağrımı daha önceden alışkın olduğumuz şekilde this anahtar kelimesi ile yapılabilir;

public class Ogrenci(string adi, string soyadi) {
    {
        if (adi == null) throw new ArgumentNullException("adi");
        if (soyadi == null) throw new ArgumentNullException("soyadi");
    } 
    
    public Ogrenci(string adi, string soyadi, string bolum): this(adi, soyadi){
        Bolum = bolum;
    }
    
     public string Adi { get; } = adi;
     public string Soyadi { get;  } = soyadi;
     public string Bolum { get; set; }
}

   Harici olarak oluşturduğumuz tüm constructor’lar daha önceden olduğu gibi birbirlerini çağırabilirler. Burada dikkat edilmesi gereken tek nokta bu çağırım silsilesi içerisinde doğrudan ya da dolaylı olarak primary constructor’ın da çağrılmasıdır.

Primary constructor doğrudan ya da dolaylı olarka çağrılmadığı zaman initializer hatası alınacaktır

   Kalıtım senaryolarında Primary Constructor’lar sınıf ilklendirilmesi sırasında temel sınıf’ın base çağrısı ile ilklendirilmesini sağlayabilirler;

public class BilMuhOgrencisi(string adi, string soyadi) : Ogrenci(adi, soyadi) { 
    //...
}

   Daha da önemlisi; base çağrısı sadece Primary Constructor’larda yapılabilir. Base çağrısı yapılmadığı durumlarda temel sınıfın varsayılan constructor’ı çağırılacaktır.

   Yukarıdaki örneklerde dikkat etmeniz gereken bir nokta da primary construtor’ın aldığı parametrelerin yaşam ömürleri olmalıdır. Primary constructor parametreleri ilgili constructor fonksiyonu içerisinde, sınıf veri üyelerinin ilklendirme ifadelerinde ve temel sınıf çağrılarında kullanılabilmektedirler.

  Son olarak; primary constructor parametre isimlerinin aynı zamanda sınıf veri üyeleri ile aynı isme sahip olmasına da izin verilmektedir;

public class Ogrenci(string Adi, string Soyadi) {
    {
        if (Adi == null) throw new ArgumentNullException("Adi");
        if (Soyadi == null) throw new ArgumentNullException("Soyadi");
    }

    public string Adi { get; } = Adi;
    public string Soyadi { get; } = Soyadi;
}

Fatih Boy

Ankara'da yaşayan Fatih, bir kamu kurumunda danışman olarak çalışmaktadır. ALM süreçleri, kurumsal veri yolu sistemleri, kurumsal altyapı ve yazılım geliştirme konularında destek vermektedir. Boş zamanlarında açık kaynak kodlu projeler geliştirmeyi ve bilgisini yazdığı makalelerle paylaşmayı seven Fatih, aynı zamanda Visual C# ve Visual Studio teknolojileri konusundan Microsoft tarafından altı yıl üst üste MVP (En Değerli Profesyonel) ödülüne layık görülmüştür. İş hayatı boyunca masaüstü uygulamaları, web teknolojileri, akıllı istemciler gibi konularda Asp.Net, Php, C#, Java programlama dilleri ve MySql, MsSql ve Oracle gibi veritabanı yönetim yazılımları ile çalışmıştır. İngilizce ve Türkçe olarak yayınlanan makalelerini gerek İngilizce bloğunda, gerekse de Türkçe bloğunda bulabileceğiniz gibi web sitesinden de açık kaynak kodlu geliştirdiği yazılımlarına ulaşabilirsiniz. vCard - Twitter - Facebook - Google+

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir