İlkay İlknur

just a developer...

Visual Studio 14 CTP'de C# 6.0 Null Propagating Operatorünü(?.) Deneyin !

Daha önce  C# 6.0  ilgili yazdığım yazılarda, C# 6.0 ile gelecek olan bazı yenilikleri aslında ekibin uzun süredir yapmayı düşündüğünü ancak eski compilerlardan dolayı yapamadığından bahsetmiştim. Bu yazımızda da yine böyle bir özellikten bahsedeceğiz. Ama öncelikle değinmem gereken bir nokta var. Gelin önce oradan başlayalım.

Visual Studio 14 CTP

Visual Studio'nun Visual Studio 2013'ten sonraki versiyonunun ilk parçaları yavaş yavaş dışarı açılmaya başlandı. Kod adı Visual Studio 14 olan ürün 2015 yılı içerisinde RTM olacak.(Bu yüzden Visual Studio 14 diye kitap yazacakları şimdiden uyarıyorum :)) Ancak yeni Visual Studio RTM olana kadar Microsoft, CTP sürümleriyle yeni Visual Studio içerisindeki özellikleri developerların testine açıyor. İlk CTP bundan 1 ay önce Haziran ayında gelmişti. Bu yazı yazıldığı zamanlarda ise 2. CTP sürümü yayınlandı.

Nasıl Yükleriz ?

Microsoft, Visual Studio 14 CTP için şu anda production ortamında kullanım desteği vermiyor. Ayrıca Visual Studio 14'ün önceki Visual Studio versiyonlarıyla beraber yan yana(side by side) çalışma durumuda şu an için yok. Bu yüzden önerim Visual Studio 14'ü kesinlikle günlük development yaptığınız makinaya kurmamanız. Bilgisayarınızda bir VM açıp oraya kurabilirsiniz. Güncel Visual Studio 14 CTP versiyonunu da buradan bulup download edebilirsiniz. Ama "Yok ben VM ile uğraşmak istemiyorum.  2 saat Windows kur zor iş..." diyorsanız ve Windows Azure hesabınız(Eğer MSDN hesabınız varsa MSDN hesabınızla beraber içerisinde belirli bir kotaya kadar kullanma limiti olan bir Azure hesabı da geliyor.) da varsa çok süper bir fırsat sizi bekliyor. Azure'da Visual Studio 14 CTP yüklü bir VM :)

Azure'da Visual Studio 14 CTP yüklü bir VM'i nasıl yaratacağınızı aşağıda görebilirsiniz.

Null Propagating Operator (?.)

Null propogating operator şu anda User Voice'de  C# içerisinde olması en çok istenen özelliklerden biri. Özet olarak bu özellikle daha az kod yazarak null kontrolü yapabiliyoruz.

Örneğin aşağıdaki koda bakarsak,

class Program
{
    static void Main(string[] args)
    {
        Customer customer = GetCustomer();
        string name = null;
        if (customer != null)
        {
            name = customer.Name;
        }
    }

    static Customer GetCustomer()
    {
        Customer customer = null;
        bool createNew = Convert.ToBoolean(new Random().Next(0, 1));
        if (createNew)
        {
            customer = new Customer()
            {
                Id = 1,
                Name = "ilkay"
            };
        }
        return customer;
    }
}
public class Customer
{
    public int Id { getset; }
    public string Name { getset; }
}

Yukarıdaki koddaki Main metodu içerisindeki kullanıma bakarsanız GetCustomer metodundan dönen Customer'ın Name propertysini alabilmemiz için null kontrolü yapmamız gerekti. Bu yapmamızın temel nedeni de GetCustomer metodunun her zaman bir Customer nesnesi dönmemesi. Yani duruma göre Customer nesnesi duruma göre de null dönmesi. Tabi ki yukarıdaki durumun normalde karşınıza çıkması çok da olası değil. Yani kimse random olarak bir metotdan nesne dönme durumunu yaratmaz eğer deli değilse :) O yüzden yukarıdaki durumu database'den data çektiğiniz ve verdiğiniz filtreye göre de kaydın DB'de olma veya olmama durumu olarak düşünebilirsiniz.

Esas konumuza geri dönersek, yukarıdaki durumlarda bir nesnenin belirli propertylerine ulaşmak istediğimizde null kontrolü yapmamız kodumuzun güvenli bir şekilde çalışması için zorunlu. Hal böyle olunca bu şekilde kontrollerin gerektiği her yerde yukarıdaki gibi if statementları yazmak durumunda kalıyoruz ve bu da kodumuzun hem biraz kirli gözükmesine neden oluyor hem de bizler developer olarak biraz daha fazla kod yazıyoruz.

Peki null propagating operator ne getiriyor ? derseniz, null propogating operator ile bir property'e veya metoda erişirken null kontrollerini bir operator kullanarak yapmanızı sağlıyor ve böylece fazladan if yazmaktan kurtuluyorsunuz. Bu operatör ile ilgili gerçek düşüncelerimi paylaşmadan önce gelin bu operatörü nasıl kullanacağımıza bakalım.

Visual Studio 14 CTP'de Ufak Bir Ayar

Bu özelliği Visual Studio 14 CTP'de kullanabilmek için ufak bir ayar yapmak gerekiyor. İlk olarak test için bir proje yarattıktan sonra projenin .csproj uzantılı proje dosyasını açıp içerisine <LangVersion>Experimental</LangVersion> tagini eklemek gerek. Bu ayarın tam olarak nasıl yapılacağını aşağıda görebilirsiniz.

Yukarıdaki ayarı da yaptıktan sonra gelelim bu operatörü nasıl kullanacağımıza. Yukarıda bahsettiğim null propagating operatorü ?. 'dır. Yani null olması muhtemel olan bir nesnenin herhangi bir property veya metoduna erişmek istediğinizde bu erişimi . kullanarak değilde ?. kullanarak yaparsanız null kontrolünü otomatik olarak yapmış olursunuz. Null propagating operatörünü kullanarak yukarıda yazdığımız Main metodunu şu şekilde yazabiliyoruz.

static void Main(string[] args)
{
    Customer customer = GetCustomer();
    string name = customer ?.Name;
}

Gördüğünüz gibi kullanımı oldukça basit ve sizi if kontrolü yapmaktan kurtarıyor. Kontrol sırasında eğer customer null ise Name propertysine erişilmeden null değeri name değişkenine atanıyor. Eğer customer null değilsede customer nesnesi içerisindeki Name propertysindeki değer name değişkenine aktarılıyor.

Güzel ve Tehlikeli Taraflar

Gelelim bu özelliğin güzel ve tehlikeli taraflarına. Öncelikle belirtmem gerekirse bu özellik %90 oranında C# 6.0'da olacak. Yani Microsoft her ne kadar biz şu anda bu özelliği experimental olarak yaptık dese de bence bu özellik çok yüksek bir ihtimalle yeni versiyonda gelecek. Bir karar verip biz bunu yapmaktan vazgeçtik derlerse büyük süpriz olur. Bu özelliğin tahmin edeceğiniz üzere güzel tarafı bizim daha az kod yazamamızı sağlaması. Ancak tabi içerisinde bazı tehlikelerde barındırıyor. Öncelikli olarak en büyük korkum 1-2 sene sonra aşağıdaki gibi kodlar görmek :)
string a = b?.c?.d?.e();
Her ne kadar bu kadar da olmaz desek de bunlar olacak. O yüzden ben bu özelliğin oldukça fazla suyunun çıkarılacağını, kodun okunulabilirliğinin ve bakımının da oldukça düşeceğini düşünüyorum. Bu yüzden de zamanında C# 6.0 planlamasında bu özellikle ilgili olumsuz oy kullanmıştım :)  Siz ne dersiniz ? Var mı beni bu düşüncemden vazgeçirecek kimse :)


Yorum Gönder


Yorumlar

  • profile

    Onur Er

    • 24
    • 9
    • 2014

    Ali bey, ben de sizin gibi yazıyorum o satırı ama gerçekten çok çirkin görünüyor. Hep buna bir çözüm istemiştim. Sonunda düşünüp yapmışlar. Çok sevindim. Bence string a = b?.c?.d?.e(); kullanımının bir sakıncası yok. Çünkü zaten normal bir programcının yazmak istediği şey şudur... string a = b.c.d.e(); Ama muhtemel null hatası yüzünden bunu yapamıyorduk ve Ali beyin dediği gibi çirkin iğrenç vıcık vıcık yöntemlere mecbur kalıyorduk. Tüm bu iğrençliklerden kurtulup string a = b?.c?.d?.e(); şeklinde yazmak bence iyi bir gelişme. Sadece birazcık çirkin diyebiliriz ama idare eder.

  • profile

    Ali Özdemir

    • 15
    • 7
    • 2014

    Bence gerek yok :) Çünkü kodlarım şu şekilde bir kontrol yapıyorum ve bu kontrol beni kodlarken yormuyor. Okunurlukta hiç düşmüyor. string name = customer != null ? customer.Name : string.Empty;

  • profile

    Emre KAÇAN

    • 12
    • 7
    • 2014

    İlkay Bey. Yazınız için teşekkür ederim. Benim için çok çok güzel bi özellik. Çünkü her yerde null kontrolü yapmaktan kod çok kirleniyor. Ve aklıma ilk gelende sizin en altta bahsettiğiniz o suyunu çıkaranlara verdiğiniz örnekti :) Çünkü entity framework içerisinde bu tip kullanımları yapıyorum. Örneğin; var kullanici = db.Kulllanici.Find(1); var ilAd = kullanici.KullaniciAdres.Ilce.Il.Adi; Yukardaki örnek sizin string a = b?.c?.d?.e(); örneği ile nerdeyse aynı. Ama bu tip kullanımlar oluyor. Bilmiyorum yukardaki kod yanlış mı ama ben bir kullanıcının iline erişirken böyle bir kod yazmam gerekiyor ve sırayla kullanıcı, kullanıcı adres, ilce ve il kontrolleri yapmam gerekiyor. (Tabi il ilçe çok istisna ama işi sağlamak almak gerekiyor.) Velhasılkelam bence dört dörtlük bir özellik olmuş :) Benim gibi null Exceptiondan bıkmış usanmış biri için biçilmiş kaftan. Umarım düşüncenizden vazgeçirebilmişimdir :) Tekrar teşekkürler kolay gelsin.