İlkay İlknur

just a developer...

Visual Studio 14 CTP 3'de Yeni Neler Var ?

Visual Studio'nun 2013'den sonraki sürümü olacak olan Visual Studio 14'ün 3. CTP sürümü 18 Ağustos'da yayınlandı. Daha önceki yazımızda CTP 1 ve CTP 2'de yeni nelerin geldiğini incelemiştik. Bu yazımızda da 3. CTP ile Visual Studio 14 içerisine neler eklendiğini inceleyeceğiz.

Visual Studio 14 CTP sürümlerini nasıl indiririm ve nasıl test ederim diyorsanız daha önce yazmış olduğum yazımı okuyabilirsiniz.

.NET Framework vNext

.NET Framework'ün bir sonraki versiyonu,  CTP 3 ile beraber Visual Studio 14 içerisine eklendi. .NET Framework vNext'in en önemli parçalarından olan .NET Native ve RjuJIT de Visual Studio 14 CTP içerisine entegre edildi. Ancak bu ürünlerin hala daha alpha sürümlerinde olduklarını unutmamak lazım.

ASP.NET vNext

Visual Studio 14 CTP 3 içerisinde ASP.NET vNext runtime'ının güncellenmiş alpha 3 paketleri bulunuyor. Ayrıca CTP 3 ile beraber ASP.NET vNext tooling support'u geliştirilmiş ve unit test desteği eklenmiş. Daha detaylı bilgi için Web Development Tools bloguna bakabilirsiniz.

Custom Window Layoutların Roam Edilmesi

Visual Studio CTP 2 ile beraber Window layoutlarını kaydedip, kaydettiğimiz layoutları istediğimiz zaman tek tıklamayla aktif hale getirip Visual Studio'nun görünümünü düzenleyebiliyorduk. CTP 3 ile beraber artık bu layoutlar roam ediliyor yani Visual Studio'ya login olduğunuz hesabınız altında saklanıyor ve başka makinalarda aynı accountunuzu kullanırsanız kaydettiğiniz layoutlara erişebiliyoruz.

PerfTips

Visual Studio 14 CTP 3 içerisinde belki de en dikkat çekici yenilik PerfTips. PerfTips size breakpoint koyduğunuz noktalarda debugging yaparken yapılan işlemlerin ne kadar sürdüğünü gösteriyor.

Perftip

C# 6.0

C# 6.0 tarafında da Visual Studio 14 CTP 3 içerisde yenilikler mevcut. En önemli yenilik ise Nameof Expressionlar.

Şimdilik CTP 3 tarafında gözüme çarpan yenilikler bunlar. Bir sonraki CTP yazımızda görüşmek üzere :)



C# 6.0 - Nameof Expressions

Başlamadan : Aşağıda inceleyeceğimiz özellik Visual Studio 14 CTP 3 ile gelen bir özelliktir. Visual Studio 14 CTP nasıl kurulur ve aşağıdaki gibi özellikleri denemek için ne yapmak gerekir  gibi soruların cevaplarını linklerde bulabilirsiniz.

Visual Studio 14 CTP 3 ile beraber C# içerisine implemente edilmiş olan özelliklerden biri de nameof expressionlar. Bazı durumlarda kod içerisinde kullandığımız değişkenlerin metotların isimlerini string olarak yazma gereği duyarız. Örneğin, bir metoda gelen parametrelerden biri null ise ArgumentNullException içerisinde gelen parametrenin adını yazarız.

void Foo(Bar bar)
{
    if(bar==null)
    {
        throw new ArgumentNullException("bar");
    }
}

Bir diğer  örnek senaryo da INotifyPropertyChanged interface'inin implementasyonu.

class Bar : INotifyPropertyChanged
{
    private int foo;

    public int Foo
    {
        get { return foo; }
        set
        {
            foo = value;
            PropertyChanged(thisnew PropertyChangedEventArgs("Foo"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Bunlara benzer kullanımlarda karşımıza çıkan en büyük sorunlardan biri de string olarak adını yazdığımız değişkenin veya metodun adını değiştirmek. Bu değişikliği yaptığımızda değişkenin adını string olarak yazdığımız için Visual Studio isim değiştirme sırasında haliyle string olarak yazılan kısmı değiştirmiyor. Örneğin, ArgumentNullException fırlattığımız örnekte metoda gelen parametrenin adını değiştirirsek aşağıdaki gibi bir durumla karşılaşırız.

Parametre adı değiştirme

Gördüğünüz gibi metoda gelen parametrenin adını değiştirdik ancak throw new ArgumentNullException("bar") kodu değişmedi. Bu durumda da bizim yazdığımız kodun içerisinde fırlatılan exception'ın içerisinde parametrenin adı eski adıyla kaldı. Böyle değişikler yaptığımız durumlarda string olarak değişkenin, metodun veya herhangi bir elemanın adını yazmak yerine C# 6.0 ile beraber gelecek olan nameof expression'ı kullanarak elemanın ismini yazma işini compilera bırakıyoruz.

void Foo(Bar bar)
{
    if (bar == null)
    {
        throw new ArgumentNullException(nameof(bar));
    }
}
INotifyPropertyChanged interface'inin nameof expression ile implemente edilmiş hali şu şekilde olacak.
class Bar : INotifyPropertyChanged
{
    private int foo;

    public int Foo
    {
        get { return foo; }
        set
        {
            foo = value;
            PropertyChanged(thisnew PropertyChangedEventArgs(nameof(Foo));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Nameof expression kullanarak elemanların isimlerini alırsak bu elemanların isimlerinde değişiklik yaptığımızda da Visual Studio bize yardımcı olacak ve nameof expression'ın içerisindeki elemanın adını da değiştirecektir.

Parametre adı değiştirme nameof Peki arka planda neler oluyor derseniz, compiler yazdığınız kodu derlerken nameof expression gördüğü yerlerde verdiğiniz elemanın adını hardcode ediyor ve string olarak yazıyor. Nameof expressionlar her ne kadar ufak bir yenilik gibi gözükse de biz developerların hatalı kod yazmasını önlemesi nedeniyle bence önemli ve güzel bir yenilik olmuş.


Visual Studio 14 CTP 1 ve 2'de Neler Var ?

Yine geldik bir Visual Studio VNext yazısına daha :) Visual Studio'nun 2013'ten sonraki versiyonunun kod adı 14. Yani Visual Studio 14.  Buradaki 14 tabi yılı temsil etmiyor :) Sadece kod adı. Visual Studio 14 kod adlı ürünün 2015 yılı içerisinde RTM olması bekleniyor.

Haziran ayında ilk CTP sürümü gelen Visual Studio 14'ün Temmuz ayında da 2. CTP sürümü geldi. Bu yazımızda da bu 2 CTP sürümünde neler geliyor diye bakacağız. Ama öncelikle Visual Studio 14 CTP'yi nasıl indirebiliriz bir bakalım. Eğer başka yazılarımda nasıl kurulacağını okuduysanız aşağıdaki bölümü atlayabilirsiniz.

Visual Studio 14 CTP Kurulum

Microsoft, Visual Studio 14 CTP için şu anda production ortamında kullanım desteği vermiyorAyrı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.

Roslyn Compilerları

Visual Studio 14 ile beraber Roslyn compilerları artık eski compilerlarla yer değiştiriyor. Yani yeni Visual Studio 14 ile derlediğiniz projeler artık Roslyn compilerları ile derlenecek. Haliyle Visual Studio 14 CTP içerisinde C# 6.0 ile gelen yenilikleri de herhangi bir plugin vs.. kurmadan kullanabilirsiniz. Hatta Visual Studio 14 CTP içerisinde yeni bir C# 6.0 özelliği daha bulunuyor. Null propagating operator (?.)

Roslyn İle Yeni Refactoring Araçları

Roslyn compilerlarının Visual Studio içerisine eklenmesiyle refactoring toollarında da bazı güzel yenilikler var. Zaten Roslyn projesinin en öncelikli amaçlarından biri de bu şekilde refactoring araçlarının yazılmasını kolaylaştırmak. Visual Studio 14 CTP içerisindeki refactoring yeniliklerinden birini aşağıda görebilirsiniz.

ASP.NET VNext Tooling

Visual Studio 14 CTP  içerisindeki en büyük yeniliklerden biri de ASP.NET VNext toolingi. Microsoft bir sonraki ASP.NET versiyonuyla radikal değişikliklere gidiyor. Şu anda runtime'ın büyük bir kısmı yeniden yazılıyor. Bu nedenle bu yeni versiyonla ilgili toolingi de Visual Studio 14 CTP'de bulabilirsiniz.

ASP.NET VNext içerisinde neler geleceğini buradan, Visual Studio 14 içerisindeki ASP.NET VNext toolingi ile ilgili detaylı bilgiyi de burada bulabilirsiniz.

Editör Touch Desteği

Visual Studio 14 CTP 2 ile beraber editör içerisine touch desteği geldi. Eğer touch screen bilgisayarınız varsa artık editör içerisinde scrool, tap, zoom gibi gestureları kullanabilirsiniz. User Voice'te görünene göre en çok istek alan itemlardan biri ki bu özelliği yapmaya karar vermişler. Ancak ben developerların pek touch gestureları kullanarak kod yazacaklarını zannetmiyorum. Ama tabi bekleyip göreceğiz bakalım bu özelliği developerlar ne kadar benimseyecekler.

Büyük Harf Menü Başlıklarından Geri Dönüş

En çok şaşırdığım yeniliklerden biri. Visual Studio 2012 ile beraber getirdiklerinde aldıkları onca tepkiye rağmen geri adım atmamışlardı. Ancak 2 sene sonra geri adım atarak sanırım inatlarından vazgeçiyorlar :) Visual Studio 14 CTP içerisinde artık menü başlıklarının hepsi büyük harf  değil.

Visual Studio 14 CTP 1 ve 2 ile ilgili göze çarpan yenilikler şimdilik bu kadar. Yeni CTP'ler çıktıkça da blogda yenilikleri paylaşacağım. Arayüz olarak Visual Studio 2013'e göre yenilik olmadığını farketmişsinizdir. Ancak ben arayüz yeniliklerini bir konferans vs.. düzenleyerek duyuracaklarını düşünüyorum. Bu artık Build mi olur Teched mi olur ne zaman olur bilemem :) Ancak arayüzde değişiklikler olacağını biliyorum :)


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 :)


Primary Constructors ve Auto Property Initializers ile Immutable Nesne Geliştirme

Immutable nesne kavramına önceki yazılarımdan birinde değinmiştim. En özet haliyle hatırlatmam gerekirse, durumları yaratıldıktan sonra değiştirilemeyen nesnelerdir immutable nesneler. Eğer durumlarında değişiklik yapmanız gerekirse, istediğiniz yeni duruma sahip olan yeni bir nesne yaratmamız gerekir. (Daha detaylı bilgi almak için yazının başında da belirttiğim gibi ilgili blog yazısını okumanızı öneririm.)

C# içerisinde immutable nesneler geliştirmek  C# developerlar için en baştan beri tam bir eziyet halini almıştır.

Neden eziyet halini aldığını gelin aşağıdaki immutable class örneğine bakarak görelim.

public class ImmutableClass
{
    private readonly int _x;
    private readonly int _y;

    public int X
    {
        get
        {
            return _x;
        }
    }
    public int Y
    {
        get
        {
            return _y;
        }
    }
    public ImmutableClass(int x, int y)
    {
        this._x = x;
        this._y = y;
    }
}

İçerisinde sadece 2 readonly property bulunan ve property değerlerini de constructordan alan bir sınıf tanımlaması için sizce de bu kodlar fazla değil mi :) En azından bana fazla geliyor. :) Burada compilerın developerların işlerini kolaylaştırması gereken pek çok nokta var.

C# 6.0 ile çözümü amaçlanan konuların başında immutable nesneler geliyor.  Immutable nesne tanımlanmasında şimdiye kadar getirilen primary constructors ve auto-property initializers ile çözümler bulunmaya çalışılıyor. Aslında birazdan bulunan çözüme baktığınızda "bulunmaya çalışılıyor" sözümün aslında gereksiz olduğunu ve çözümün bulunduğunu da düşünebilirsiniz :)

Bakalım yukarıda C# 6.0 öncesinde geliştirdiğimiz immutable sınıfı, C# 6.0 ile beraber nasıl yazabiliyoruz.

public class ImmutableClass(int x, int y)
{
    public int X { get; } = x;
    public int Y { get; } = y;
}
Aslında herşey ortada değil mi :) Benim sanırım artık pek birşey dememe gerek kalmıyor :) Umarım faydalı olmuştur. Not : Blog yazıları haricinde sosyal medya üzerinden anlık paylaşımlarımı Twitter ve  Facebook'tan takip edebilirsiniz.


C# 6.0 - Auto-Property Initializers

C# 6.0 ile beraber gelen Auto-Property Initializers benim su ana kadar C# 6.0 içerisindeki en favori özelliklerimden biri. Bu özellikle en basit anlamda auto-propertyler için default deger atamasi yapabilmekteyiz. Simdi  ilk olarak  C# 6.0 öncesinde default deger tasiyan bir auto-property nasil yaratiyoruz buna bir bakalim.

class Foo
{
    public string Bar { getset; }
    public Foo()
    {
        Bar = "Test";
    }
}

Gördügünüz gibi ilk olarak class içerisinde bir auto-property tanimlamasi yaptik. Sonrasinda da default deger atamasi yapmak için constructor tanimlayip içerisinde default deger atamasi yaptik.

C# içerisinde bulunan auto propertyler bildiginiz gibi derleme esnasinda compiler tarafindan arka planda yeniden yaziliyorlar. Örnegin, yukarida yazdigimiz kod derlenme sirasinda asagidaki gibi yeniden yaziliyor.

internal class Foo
{
    [CompilerGeneratedDebuggerBrowsable(DebuggerBrowsableState.Never)]
    private string <Bar>k__BackingField;

 public Foo()
    {
        this.Bar = "Test";
    }

    public string Bar
    {
        [CompilerGenerated]
        get
        {
            return this.< Bar > k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            this.< Bar > k__BackingField = value;
        }
    }
}

Compilerin arka planda yaptigi transformasyonlari bir kenara birakirsak en tepedeki kullanima baktigimizda, bir auto-property için default deger atamasi yapabilmemiz için constructor tanimlamamiz sart. Yani biraz daha fazla kod yazmak zorunda kaliyoruz. Iste bu nedenden dolayi C# 6.0 ile beraber daha declarative bir sekilde default deger atamasi yapabilmemiz için auto-property initializerlar C# içerisine ekleniyor.

C# 6.0 ile beraber bir auto-property'e default deger atamasini asagidaki sekilde yapabiliyoruz.

class Foo
{
    public string Bar { getset; } = "Test";
}
Gördügünüz gibi hem daha az kod yaziyoruz hem de çok daha declarative bir sekilde tanimlamamizi yapabiliyoruz. Peki compiler kodu derlerken bu auto-property tanimlamasini arka planda nasil yeniden yaziyor ?
internal class Foo
{
    [CompilerGeneratedDebuggerBrowsable(DebuggerBrowsableState.Never)]
    private string <Bar>k__BackingField = "Test";

 public string Bar
    {
        [CompilerGenerated]
        get
        {
            return this.< Bar > k__BackingField;
        }
        [CompilerGenerated]
        set
        {
            this.< Bar > k__BackingField = value;
        }
    }
}

Sadece Getter'i Olan Propertyler Için Auto Initializerlar

C# 6.0 öncesinde sadece getter'i olan auto-propertyler yazamiyorduk. Bunun yerine auto-propertyler öncesinde kullandigimiz genisletilmis sekilde yazilan propertyler kullaniyorduk. Örnegin,
class Foo
{
    private readonly string bar = "Test";
    public string Bar
    {
        get { return bar; }
    }
}

Gördügünüz gibi sadece getteri olan bir property tanimlamak için o propertynin döndürecegi degeri içerisinde barindiran readonly fieldi da bizim yaratmamiz gerekiyor. Ancak C# 6.0 ile beraber gelen auto-property initializerlari ile artik sadece getteri olan auto-propertyler tanimlamak mümkün.

class Foo
{
    public string Bar { get; } = "Test";
}
Gördügünüz gibi C# 6.0 ile beraber sadece getteri olan property tanimlamak da oldukça basit ve declarative. Compiler'in arka planda yarattigi koda baktigimizda ise C# 6.0 öncesinde yazdigimiz koddan bir farki olmadigini görebiliriz.
internal class Foo
{
    [CompilerGeneratedDebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly string <Bar>k__BackingField = "Test";

    public string Bar
    {
        [CompilerGenerated]
        get
        {
            return this.< Bar > k__BackingField;
        }
    }
}
Sadece getter'i olan auto-propertyler özellikle bizim immutable nesneler gelistirmemizi de oldukça kolaylastiracak. Yazinin basinda da dedigim gibi bu yenilikler benim C# 6.0 içerisindeki en favori özelliklerimden biri. Sizce de çok faydali ve kolaylastirici degil mi ?

Not : Blog yazilari haricinde sosyal medya üzerinden anlik paylasimlarimi Twitter ve  Facebook'tan takip edebilirsiniz.



C# 6.0 - Primary Constructors

Bir önceki yazımızda C# 6.0 ile beraber getirilmesi düşünülen özelliklere genel bir bakış atmıştık. Şimdi sıra geldi her bir özelliği teker teker incelemeye. İlk sırada Primary Constructorlar var.

Nedir ? Ne işe Yarar ?

Primary constructorlar, bizim constructor parametrelerini doğrudan class veya struct tanımı esnasında tanımlamamızı sağlarlar. Böylece compiler da arka planda bizim verdiğimiz parametreleri kabul eden bir constructor yaratır. Hemen bir örnek vermemiz gerekirse

C# 6.0 ile Primary Constructor Tanımı

public class Event(int id, string name, string location)
{

}
C# 6.0 Öncesinde Nasıl Yazıyorduk  ? 
public class Event
{
    public Event(int id, string name, string location)
    {

    }
}

En basit anlamıyla baktığımızda primary constructorların temel işlevi yukarıda gördüğünüz gibi bizim daha az kod yazmamızı sağlamak. Şimdi işleri biraz daha karmaşıklaştıralım.

Ya Birden Fazla Constructor Olursa ?

Yazdığımız sınıflarda her zaman tek bir constructorımız olmuyor haliyle. Peki birden fazla contructor olduğunda işler nasıl işliyor ?

Özelliğin adı Primary Contructors :) İşte Primary sözcüğü tamda bu noktada devreye giriyor. :) Primary constructor syntaxı ile tanımladığınız constructor o classın öncelikli constructorı oluyor. Yani 2. bir constructorınız varsa o constructor mutlaka primary constructorı çağırmalı.

Yukarıdaki uyarı da bir önceki paragrafta söylediklerimizi onaylıyor. O zaman uyarıdan kurtulalım :)

public class Event(int id, string name, string location)
{
    public Event(int id, string name) : this(id, name, string.Empty)
    {

    }
}

Inheritance İşin İçine Girerse ?

Peki diyelim ki primary constructor tanımladığımız sınıf başka bir sınıftan türüyor. Bizim primary constructor tanımladığımız sınıfta primary constructor çalışırken türediği sınıfın constructorına istediğimiz parametreleri nasıl geçeriz ?

public class Event(int id, string name, string location)
{

}

public class SportEvent(int id, string name, string location, string teams)
    : Event(id, name, location)
{

}

Peki Partial Classlar ?

Partial classları code generation senaryoları haricinde kullanmadığınızı düşünüyorum :) Ancak aklınıza şu şekilde bir soru gelebilir : Peki ya ben farklı partial class tanımlarında farklı primary constructorlar tanımlarsam ne olur ? Daha doğrusu tanımlayabilir miyim ?

Cevap : Hayır. Partial class tanımlamalarının sadece 1 tanesinde primary constructor tanımlaması yapabilirsiniz. Eğer birden fazla class tanımında primary constructor tanımlarsanız derleme hatası alırsınız.

Bu Kod Derlenmez !!!

Bu Kod Derlenir
public partial class Event(int id, string name,string location)
{
    public Event(int id, string name) : this(id, name, string.Empty)
    {

    }
}

public partial class Event
{

}

Nerede Bu Parametreler ? Ulaşamıyorum...

En can alıcı noktayı sona bıraktım :) Eğer primary constructors özelliğini kurcalamaya başlarsanız primary constructorla gelen parametrelere bazı yerlerde ulaşabildiğinizi bazı yerlerde de ulaşamadığınızı göreceksiniz. Örneğin aşağıdaki kodlarda ilgili parametre değerlerine ulaşabiliyoruz.

public class Event(int id, string name, public string location)
{
    public int Id = id;
    public string Name { getset; } = name;
}

Not : Yukarıdaki koddaki 2. satır C# 6.0 ile beraber gelen auto propertyler initializer. Özellikle ilgili kısa bilgi almak için buraya bakabilirsiniz.

Yukarıda yapabildiklerimize karşın aşağıdaki durumlarda da constructora geçilen değerlere ulaşamıyoruz.

Bu durumdan kurtulmanın bir yolu var aslında. Class tanımı içerisinde kendi değişkenlerimizi tanımlayarak constructora geçilen parametrelerin değerleri tanımladığımız değişkenlere atayabiliriz.

Örneğin,

public class Event(int _id, string _name, string _location)
{
    int id = _id;
    string name = _name;
    string location = _location;

    public void Foo()
    {
        string str = id.ToString();
    }
}

Yukarıdaki çözüme baktığımızda aslında istediğimiz sonucu elde edebildik. Ancak tabi bazı sorunlar var. Öncelikli olarak bu primary constructors özelliği bizim daha az kod yazmamızı sağlamıyor muydu ? Biz primary constructor kullanacağız diye bu sefer son derece çirkin bir kod yazdık :) Primary constructor parametreleriyle class'ım içerisindeki değişkenlere aynı ismi veremeyeceğim için constructor parametrelerimin önüne _ koymak zorunda kaldım vs... Özetle ortalık karman çorman artık...

Tüm bu durumları neyseki C# takımı önceden düşünmüş ve bizi yukarıdaki kötü kodu yazmaktan kurtarmışlar.

Eğer primary constructor tanımlarken constructor parametrelerin başına access modifierları yazarsanız compiler arka planda sizin verdiğiniz access modifierına sahip bir değişken yaratıyor ve constructora geçilen değeri doğrudan bu değişkene atıyor.

public class Event(private int id, public string name, public string location)
{
    public override string ToString()
    {
        string str = "Name=" + name + " Location=" + location;
        return str;
    }
}

Bitirirken

Primary Constructorlar gördüğünüz gibi bizim kod yazmamızı oldukça kolaylaştırıyor. Ancak genel yapıya baktığımızda bu özellikle ilgili mutlaka bilmemiz gereken detaylar da var. Bu detayları bilmediğimizde ortada takılıp kalmamızda oldukça muhtemel. C# 5.0 async ile beraber aslında programlama dilinde tahmin edilebilir yapılar yerine bilinmesi gereken yapılar tarafına doğru bir kayma var. Neyse bu konu oldukça uzar gider. Bende bu yazıyı bitiremem. Başlı başına bir yazı konusu bu. Umarım faydalı olmuştur. Not : Blog yazıları haricinde sosyal medya üzerinden anlık paylaşımlarımı Twitter ve  Facebook'tan takip edebilirsiniz.


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.