25 Mart 2018 Pazar

Null-coalescing (? ?), Ternary (? :), Monadic Null-Checking (?)

      S.a. Arkadaşlar,
     Bugün yazacağımız konu soru işaretinin(?) ne işe yaradığı ile ilgili olacaktır. Aslında basitçe bir if-else görevi görmektedir, fakat bununla birlikte bazı işlerde gayet kısa işlemler de yaptırıyor bize. Biz bugün ? , ? : , ?? işleçlerini ele almayı deneyeceğiz. Şimdi başlayalım.
      İlk önce en bilinen yapısıyla kullanalım. If else yapısından bahsediyorum. Aslında diğer yapılarda da yine karşımıza çıkmaktadır. Ama bu işin temelidir. ?: ifadesinden bahsediyoruz. Bu ifadeyi C#, Java'da görebiliriz. Tabi başka kullanılan diller de mevcuttur.Şimdi bir örnek verelim ve bu örnek üzerinden devam edelim.
bool IsPositive;
int y=5;
if(y>0)
{
    IsPositive = true;
}
else
{
    IsPositive = false;
}

     Şimdi yukarıda basit bir ifade kullandık. Fakat bunu daha kısa şekilde nasıl halledebiliriz derseniz işte tam da burada ?: devreye girmektedir. Bunu aşağıda göreceğiniz şekile çevirebiliriz.
bool IsPositive = y>0 ? true : false;

       Peki bu tarz kullanımın bize ne gibi avantaj veya dezavantajı olur diyorsanız, onu da kısaca açıklayalım.
      Öncelikle gördüğünüz gibi kod satır sayısını azaltıyoruz ve okunurluğu artırıyoruz. Bununla birlikte tek seferde atama işini hallediyoruz. Tabi bu avantajı dezavantaja da çevirmemek lazım. Çünkü bunu kötü kullanıp aşağıdaki gibi koda çevirmemek lazım diye düşünüyorum.
int result = FirstCheck() ? 1 : SecondCheck() ? 1 : ThirdCheck() ? 1 : 0;

     Dediğim gibi bu ifadeyi kısa ifadelerde kullanmak daha mantıklı. Yoksa okunurluğu artırmak yerine , işin içinden çıkılmaz hale getirebiliriz. Daha karmaşık işler için if else yapısını kullanmak daha uygun olacaktır.

       Burada atama işlemi yaparken atanacak ifadelerin değerinin tipleri aynı olmalıdır. Yoksa cast işlemi yapmak gerekir.
long? realtedId;
long Id ;
realtedId = Id != 0 ? (long?)Id : null;

      Örnekte görüldüğü gibi realtedId null olabiliyorken Id null değeri alamaz. Şimdi soldaki Id değeri sadece 0 olabiliyorken , sağda null atanmış. Burada tipler uyuşmadığı için kodumuz hata verecektir. Bunu ya cast etmemiz gerekecektir yukarıda bahsettiğimiz gibi veya null yerine 0 yazmamız gerekecektir. 0 yazdığımız takdirde (long?) ifadesini kullanmamıza gerek kalmayacaktır. İşin mantığı tiplerin aynı olması gerektiğidir.

     Şimdi ise null kontrolü yapan yapıyı kontrol edelim. Bunun Java'da karışılığı yok diye biliyorum. Yanılıyorsam düzeltin lütfen.  Her hangi bir null kontrolü yaptığımızda ne yapıyoruz.
object anyoneObject = new object();
if (anyoneObject != null) {
    // ...
} 
   
      Peki biz bu kontrolü içine bir kontrol daha yapmak zorunda yine bir if belki sonra yine bir if mi yazmak zorundayız. Hayır. Bu sefer de null kontrolü için kullanacağız ? işlecini :)
var Y = anyoneObject?.X;
 
       Burada objeyi kontrol ediyoruz ve null değilse o objeye ait bir özelliği atıyoruz. Eğer biz ? kullanmamış olsak ve obje değeri null döner program kırılacaktır. (tabi ki try catch kullanmamışsak :))

       Şimdi de ?? işlecini ele alalım. Aslında bu işleç bir nevi kontrol işlemi yapmaktadır, ama bir farkla. Eğer değerimiz null olursa atayacağımız değer null değil de başka bir değer olmasını istiyorsak bunu kullanabiliriz. Hemen örneğimizi inceleyelim.
var ID = ObjectX?.ObjectY?.Id ?? 0;

       Burada ObjectX kontrol ediyoruz , sonra ObjectY , eğer bunlar null değilse Id değerimizi atıyoruz. Eğer bu objelerden biri null ise otomatik olarak sağdaki 0 değerini veriyoruz. Yani kısaca şöyle diyebiliriz. Değer null değilse soldaki değeri veriyoruz, aksi durumda sağdakini veriyoruz.

      Şimdi ise C#7 ile gelen bir özellikten bahsedeceğiz, bunu daha önceki C# sürümlerinde kodlarsanız hata alacaksınız. Yukarıdaki işlemde eğer objelerden biri null olursa sağdaki 0 değerini alırız demiştik, fakat 7 ile gelen bu yeni özellik sayesinde bir değer vermek zorunda değiliz, bunun yerine bir hata fırlatabiliriz. Şimdi aşağıdaki örneğimizi inceleyebiliriz.
int x = 5;
int Number = x / 0 ?? throw new DivideByZeroException("Bölüm Sıfır Olamaz!");

  Bilinçli ve güzel kod yazmak dileğiyle. Hoşça kalın.

https://denizirgin.com/c-7-0-yenilikleri-28a82f758fe8
http://enterprisecraftsmanship.com/2015/05/11/3-misused-of-operator-in-c-6/
https://stackoverflow.com/questions/3312786/benefits-of-using-the-conditional-ternary-operator

Hiç yorum yok:

Yorum Gönder