İlkay İlknur

just a developer...

Bir Solukta C# 6.0

Build'in 2.gün özetinde size Roslyn ve yeni C# versiyonu olan C# 6.0 versiyonundan bahsetmiştim. Hatta twitter'dan veya Facebook'tan takip ediyorsanız gelen yenilikleri açıklandığı gibi paylaşmıştım.

Bu yazıda da istiyorum ki C# 6.0 ile beraber gelmesi muhtemel özelliklere kısaca bir göz atalım. Gelmesi muhtemel özellikler diyorum çünkü buradaki özelliklerde henüz tasarım aşamasındalar. Yani bahsettiğim bir özellik bir bakmışınız 2 ay sonra değişmiş :)

Nasıl Deneriz

C# 6.0 ile beraber gelmesi muhtemel özellikleri test etmek için Roslyn End User Preview'ı kurmanız yeterli. Roslyn End User Preview içerisinde yeni C# ve VB compilerları ile Roslyn kullanarak implemente edilmiş Visual Studio özelliklerini bulunuyor.

Roslyn End User Preview bir Visual Studio extensionı (.vsix) olarak geliyor. Yani doğrudan çift tıkla bilgisayarınıza yükleyebilirsiniz.

Peki Ya Kaldırmak İstersek

Roslyn compilerları henüz preview aşamasındalar. Yani productionda kullanılması doğru değil ve Microsoft tarafından da desteklenmiyor. Bu yüzden diyelim ki kodunuzu yazdınız ve production ortamına kodu atmanız gerekiyor. Bunun için Roslyn compilerlarını devre dışı bırakıp şu anki eski compilerlarla kodunuzu derlemeniz gerekiyor. Bunu yapmak için Visual Studio 2013 içerisindeki Extensions ekranını kullanarak Roslyn extensionını devre dışı bırakabilirsiniz.

Unutmadan, extensionı disable ettikten sonra Visual Studio'yu yeniden başlatmak gerekiyor.

Rosly'nin kurulumu ve kaldırma işlemleri bu basit. Artık uçuşa geçmek için hazırız :) O zaman başlıyoruz...

Primary Constructors

Primary constructorlar, en basit anlatımla bizim constructor parametrelerini class veya struct tanımında yapmamızı sağlar.

Örneğin,
public class Insan(string name,string surname)
{

}

Biraz farklı geldi değil mi :)

Burada aslında yapmak istediğimiz şey Insan tipi içerisine name ve surname adında string parametreleri olan bir constructor eklemek ve bu constructora geçilen parametrelerin değerlerini de class içerisindeki name ve surname isimli fieldlarda saklamak. Özetle yukarıda yazdığımız kodun şu an kullandığımız versiyon olan C# 5.0'da karşılığı şu şekilde.
public class Insan
{
    private string name;
    private string surname;

    public Insan(string name, string surname)
    {
        this.name = name;
        this.surname = surname;
    }
}

Gördüğünüz gibi primary constructors ile beraber yukarıdaki gibi kod yazmaktan kurtulmuş oluyoruz ve böylece class veya struct'ın tanımlanması sırasında o tiple ilgili bazı özellikleri bildirebiliyoruz. Primary constructorsla beraber immutable nesne geliştirme de artık oldukça kolaylaşacak. Bu konuya başka bir makale de değineceğim...

Auto Propertyler İçin Initializer

C# 6.0 ile beraber gelen ve benim en beğendiğim özelliklerden biri olan auto property initializerları ile auto propertyler için daha kolay bir syntax ile değer ataması yapabiliyoruz. Örneğin,
public class Insan
{
    public string Name { getset; } = "Mahmut";
    public string Surname { getset; } = "Batmaz";
}

Yukarıda görmüş olduğunuz syntax ile Name ve Surname propertylerine default değer ataması yapabilmekteyiz.

Eğer Name ve Surname propertylerini immutable yapmak isterseniz property tanımı içerisindeki setterı kaldırırsanız Insan tipi içindeki propertylerin sürekli olarak "Mahmut" ve "Batmaz" değerlerini döndürdüğünü görebiliriz.

public class Insan
{
    public string Name { get; } = "Mahmut";
    public string Surname { get; } = "Batmaz";
}

Using Static

Açıkca söylemem gerekirse bu özellik de C# 6.0 içerisinde en beğenmediğim özellik :) Yalan yok. İlk gördüğümden beri alışamadım. Eğer VB kullandıysanız bu özelliği zaten VB tarafından hatırlayacaksınız. Özetle bir tip içerisindeki static metotları tipin adını belirtmeden kullanmanıza olanak sağlıyor. Örneğin, Math tipi içerisindeki static metotları kullanmak istediğimizde şu şekilde bir kod yazmamız gerekiyor.

using System;

namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            double x = Math.Pow(2, 3);
        }
    }
}

Ancak C# 6.0 ile beraber tipin adını using ifadesine ekleyerek tip ismi kullanmadan doğrudan metot adıyla metodu çağırabilmekteyiz.

using System.Math;

namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            double x = Pow(2, 3);
        }
    }
}

Büyük projelerde bu şekilde kullanımların karışıklığa neden olacağını düşünüyorum. Özellikle eklenecek birden fazla static tiple beraber Intellisense static metotlarla dolacaktır. Bunun yanında kodun okunabilirliği açısından bu özelliğin negatif bir etkisi olacağını düşünüyorum.

Declaration Expressions

Gelelim C# 6.0'daki en sevdiğim özelliğe :) Bu özellikle beraber artık expressionlar içerisinde tanımlama yapabiliyoruz. Bunun en  güzel kullanım yeri de out parametreler.
namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = "123";
            bool isParsed = int.TryParse(s, out int result);
        }
    }
}

Exception Filters

VB ve F#'ta olup da C#'da olmayan özelliklerden biri de exception filters. Exception filters ile catch ifadeleri içerisine filtreler yazabiliyoruz. Böylece yazdığımız catch bloğunda sadece bizim verdiğimiz exception filtresine uygun exceptionlar yakalanıyor. Filtreye uymayan exceptionlar ise stacktrace'i kaybolmadan yoluna devam ediyor.

Örneğin,
using System;
using System.Data.SqlClient;

namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Do Operation");
            }
            catch (SqlException sqlEx) if (sqlEx.Number == 100)
            {
                Console.WriteLine("Log Exception");
            }
        }
    }
}

Indexed Element Initialization

C# içerisindeki object ve collection initializerları ile çok hızlı bir şekilde object ve collectionlar tanımlayıp ilgili alanlara değer atamalarını veya eleman eklemelerini çok hızlı bir şekilde yapabiliyoruz.

C# 6.0 ile beraber bu özelliklere ek olarak artık initializer içerisinde belirli indexteki elemalara da atama yapmak mümkün hale geliyor.

using System.Collections.Generic;

namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int>()
            {
                [2] = 1,
                [8] = 10
            };

            Dictionary<stringstring> dic = new Dictionary<stringstring>()
            {
                ["key1"] = "value1",
                ["key12"] = "value2"
            };
        }
    }
}

Indexed Member Access

Bu özellik de açıkcası C# 6.0'da şu ana kadar en garipsediğim özellik :) Bu özellikle beraber artık string index üzerinden eriştiğimiz elemanlara daha kolay bir syntax ile erişebilmekteyiz. Yani eskiden foo["bar] şeklinde yazdığımız kodu C# 6.0 ile beraber foo.$bar şeklinde yazabilmekteyiz.

using System.Collections.Generic;

namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<stringstring> dic = new Dictionary<stringstring>();
            dic.$key1 = "value1";
            dic.$key12 = "value2";
        }
    }
}

Hatta bir önceki maddedeki özellikle bu özelliği birleştirip collection initializerların yazımını kolaylaştırmak da mümkün.

using System.Collections.Generic;

namespace ConsoleApplication37
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<stringstring> dic = new Dictionary<stringstring>()
            {
                $key1 = "value1",
                $key12 = "value2"
            };
        }
    }
}

Catch ve Finally Bloklarında Await Kullanımı

C# 5.0 ile beraber async-await keywordleri geldiğinde en büyük kısıtlamalardan biri catch ve finally bloglarında await keywordünün kullanılamamasıydı. Eğer async loglama metotlarınız varsa veya finallyde nesneleri async olarak dispose etmek veya close etmek istiyorsak asenkron metotları senkron olarak çağırmak zorunda kalıyorduk. Ancak C# 6.0 ile beraber artık bu kısıtdan da kurtuluyoruz.

private static async Task DoAsync(Resource resource)
{
    try
    {
        resource.DoOperation();
    }
    catch (Exception ex)
    {
        await LogAsync(ex);
    }
    finally
    {
        await resource.CloseAsync();
    }
}

Bitirirken...

C# 6.0 ile beraber gelmesi muhtemel özellikleri kısaca inceledik. Zaten ilerleyen günlerde her özellik için ayrı ayrı detaylı yazılar yazacağım. Ancak bu yazıda istedim ki ilk dalgada gelen özelliklere genel bir bakış atalım.

C# 6.0 ile gelen özelliklere baktığımızda aslında bu versiyonda dilin herhangi bir baskın temasının olmadığını görüyoruz. Yani C# 5.0'da tema async programlama iken C#  4.0'da ise dinamik programlama ana temaydı ve bu temalara yönelik çalışmalar yapılmıştı. Ancak bu versiyonda developerların işlerini kolaylaştıracak pek çok ufak tefek özelliğin geldiğini görüyoruz. Bu özelliklerle beraber de artık daha hızlı kod yazabilme imkanına sahip olacağız.

Bu versiyonda neden bu şekilde bir tema olmadan ilerlendi diye sorabilirsiniz :) Birinci neden şu anda programlama dünyasında çözülmesi gerek majör bir problemin olmaması. İkinci neden ise bu özellikleri C# ekibinin uzun zamandır yapmak isteyip de eski compiler kodları yüzünden yapamaması. Çünkü artık Roslyn compilerlarıyla bu yukarıda gördüğünüz gibi özellikleri çok daha hızlı bir şekilde dil içerisine ekleyebiliyorlar.

Yazının en başında da bahsettiğim gibi bahsettiğim özellikle şu anda End User Preview'da olan özellikler. İlerleyen dönemlerde yeni preview versiyonları çıkacak ve yeni dil featureları da dil içerisine eklenecektir. Ancak yeni previewları beklemeden C# ve VB programlama diline getirilmesi planlanan özelliklere buradan erişebilirsiniz.

Görüşmek Üzere,

Not : Blog yazıları haricinde sosyal medya üzerinden anlık paylaşımlarımı Twitter ve  Facebook'tan takip edebilirsiniz.



Yorum Gönder


Yorumlar

  • profile

    Mustafa Demirel

    • 16
    • 8
    • 2016

    Açıklama için Teşekkürler.

  • profile

    Ercan

    • 10
    • 4
    • 2014

    Makalenizi okuduğumda daha ne olabilir diye düşündüm ama birkaç şeyin dışında zaten birçok şeyin fazlasıyla yapıldığını düşünüyorum. Bilgilendirici ve güzel bir yazı olmuş.