C# 6.0 – Record Sınıfı (Taslak Önerisi)

   Özellikle Roslyn projesinin .NET Compiler Platform adıyla açık kaynak olarak geliştirilmeye devam etmesi ardından C# 6 çalışmaları da ivmelendi. Açık kaynak kod geliştiricilerinden destek gelmesi ve C#’a yeni özellikler katma isteği bu ivmenin dinamikleri arasında yer alıyor. Çalışmalar hızla devam ederken, geçtiğimiz hafta içerisinde yeni bir gelişme yaşandı. C# diline yeni bir özellik eklenmesi konusunda yeni bir taslak önerisi sunuldu; Pattern Matching (Desen Eşleştirme).

UyariBu makalede paylaştığım Record Class henüz taslak aşamasındaki bir öneri olup C#’a dahil edilip edilmeyeceği, C# 6.0 ile gelip-gelmeyeceği çok kısa bir süre önce tartışmaya açılmıştır. İlerleyen zamanlarda topluluklar içerisindeki fikir alış-verişleri neticesinde nihayi şeklini alırken değişikliğe uğrama olasılığı yüksektir.

 

locked   Bu adresten ulaşabileceğiniz söz konusu taslağı incelemeye başladığınızda sizi Record ve Pattern Matching kavramları karşılayacaktır. Mevcut durumda C# içerisinde Immutable Object (değişmez nesne) oluşturmak için nesnenin salt-okunur özelliklerini oluşturmamız, ardından da bu özelliklere değer atılabilecek constructer’ı oluşturmanız gerekiyor, HashCode, ToString ve Equals fonksiyonlarının yazılması gereksinimi saymıyorum bile. Bu adımları takip ederek basit bir iş mantığı için bile tam anlamıyla immutable bir nesne oluşturmak bile bize işkence haline gelebilir. Bu noktada sahne alan Record tanımını C#’ta daha kolay Immutable Object tanımlamaları önemli için bir adım olarak düşünebilirsiniz.

class-declaration:
    attributesopt   class-modifiersopt  partialopt  record class   identifier   type-        parameter-listopt
        record-parametersopt   class-baseopt   type-parameter-constraints-clausesopt
        class-body

record-parameters:
    (  record-parameter-listopt   )

record-parameter-list:
    record-parameter
    record-parameter-list  , record-parameter

record-parameter:
    attributesopt  type identifier record-property-nameopt default-argumentopt

record-property-name:
    : identifier

class-body:
{   class-member-declarationsopt   }
;

   Record sınıfı tanımıyla birlikte dikkat edecek olursanız alışageldiğimiz sınıf tanımlamasında da ufak değişiklikler yapılmış. Record sınıfları amaçları nedeniyle bir body (gövde) içermek zorunda olmadıkları için “;” ile tanımın sonlandırılmasına izin verilmiş. Konuyu taslakta verilen örnek üzerinden biraz daha açarak record class (Kayıt sınıfı) kavramının kafanızda daha netleşmesini sağlayalım;

public record class Cartesian(double x: X, double y: Y);

   Temelde anonim türlerin bir adım ileri taşınmış versiyonu olarak da görebileceğiniz record sınıfları yukarıdaki şekilde sade olarak tanımlanabilmektedir. Bu tanımlama ile arkasındaki derleyici desteği sayesinde bize hızlıca aşağıdaki özelliklere sahip bir sınıf oluşturma imkanı sunmakta;

  • Belirttiğimiz parametreleri kabul eden bir primary constructer
  • Belirttiğimiz her bir özellik için salt okunur bir property (record sınıf tanımlaması içerisinde “:”dan sonra belirttiğiniz  tanımlayıcı bu property’leri isimlendirmede kullanılacaktır)
  • Equals fonksiyonu
  • GetHashCode fonksiyonu override
  • ToString fonksiyonu override
  • is operatörü

   is operatörü de record sınıfı gibi yeni tanıştığımız bir operatör. Detaylarına bir sonraki makalemde paylaşacağım is operatörü sayesinde is ve switch işlemlerinde daha fazla kontrole sahip olabileceğiz.

   Taslakta yukarıdaki örnek ardından derleyicinin oluşturduğu kod için aşağıdaki çıktı gösterilmektedir;

public class Cartesian {
  private readonly double $X;
  private readonly double $Y;
  public Cartesian(double x, double y) {
    this.$X = x;
    this.$Y = y;
  }
  public double X { get { return this.$X; } }
  public double Y { get { return this.$Y; } }

  // compiler-generated pattern-is operator
  public static bool operator is(Cartesian c, out double x, out double y) {
    x = c.X;
    y = c.Y;
    return true;
  }
  override public bool Equals(object obj) {
    var $o = obj as Cartesian;
    return !ReferenceEquals($o, null) && object.Equals(X, $o.X) && object.Equals(Y, $o.Y);
  }
  override public int GetHashCode() {
    int $v = 1203787; 
    $v = ($v * 28341) + X?.GetHashCode().GetValueOrDefault();
    $v = ($v * 28341) + Y?.GetHashCode().GetValueOrDefault();
  }
  override public string ToString() {
    return new System.Text.StringBuilder()
      .Append(“Cartesian(X: “)
      .Append(X)
      .Append(“, Y: ”)
      .Append(Y)
      .Append(“)”)
      .ToString();
  }
}

   Record sınıfları da normal sınıf kurallarına tabidir. Bu durumda normal sınıflarda olduğu gibi ek property ve fonksiyon tanımlamaları yapılabilir. Hatta, derleyicinin varsayılan olan tanımladığı is operatörü override edilerek özelleştirilebilir.

   Mevcut taslak şu an için sadece record anahtar kelimesinin sınıflarda kullanımına izin verse de taslağın ilerleyen sürümlerinde struct’larında bu kapsam içerisine alınması düşünülmekte.

   Bir sonraki makalemde, birlikte is operatörü ve pattern matching taslağının detaylarını inceleyeceğiz.

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