C# 6.0 ile Gelen Yenilikler

Microsoft C# 6.0 'ı daha önce release ettiği sürümlere istinaden çok büyük major feature'lar ile kullanıma sunmadı desek çokta yanlış olmaz herhalde. Ancak 6.0 ile major feature'ların dışında geliştirici için development yapmasını çok daha kolaylaştıracak diyebileceğimiz bir takım önemli değişiklikler sundu. Daha öncesinde aynı işlemleri yapabilmek için satırlarca kod yazdığımız işlemler artık birkaç satırda yapılabilecek duruma gelmiş. 

6.o ile gelen feature listesi aşağıda ki gibidir.

 

1) Auto-Property Initializer

Daha önceki C# sürümlerinde field'lar için kullanılabilir olan initializer artık auto-property'ler için de kullanılabilecek. 

Öncesinde

using System;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer cust = new Customer();
            Console.WriteLine(cust.customerID);
            Console.ReadLine();
        }
    }

    public class Customer
    {
        public Customer()
        {
            customerID = Guid.NewGuid();
        }
        public Guid customerID { get; set; }
    }
}

 C# 6.0 ile

using System;
using static System.Console;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer cust = new Customer();
            WriteLine(cust.customerID);
            ReadLine();
        }
    }

    public class Customer
    {
        public Guid customerID { get; set; } = Guid.NewGuid();
    }
}

  

2) Using Static

Daha önceleri projede ilgili class'ta herhangi bir yerde static sınıfları kullanmak istediğimizde sınıfın adıyla birlikte o sınıfın fonksiyonlarını çağıra bilmekteydik. 

Öncesinde

class Program
{
    static void Main()
    {
        Console.WriteLine(Math.Sqrt(5*2 + 4*3)); 
        Console.WriteLine(System.DayOfWeek.Friday - System.DayOfWeek.Monday); 
    }
}

Artık C# 6.0 ile birlikte bu statik sınıfları using ile tanımlayıp sonrasında o sınıfa ait metotları kullanabileceğiz. 

C# 6.0 ile

using static System.Console;
using static System.Math;
using static System.DayOfWeek;
class Program
{
    static void Main()
    {
        WriteLine(Sqrt(5*2 + 4*3)); 
        WriteLine(Friday - Monday); 
    }
}

 

3) Expression-bodied methods

Lambda expresiion C# 3.5 ile gelen en büyük değişiklikti ve lambda sayesinde uzuuunnn mu uzun delegate kodları yazmaktansa o satırlara karşılık gelen lambda tanımlamalarını yazabilmekteyiz. Eğer yazılan metod geriye tek satırlık bir işlem yapıp değeri return ediyorsa bu işlem lambda expression ile de yazılabilecektir. 

Öncesinde

namespace CSharpSix
{
    class Program
    {
        private static double MultiplyNumbers(double num1, double num2) 
        { 
           return num1 * num2;
        }

        static void Main(string[] args)
        {
            double num1 = 3;
            double num2 = 6;

            Console.WriteLine(MultiplyNumbers(num1, num2));
            Console.ReadLine();
        }
    }
}

C# 6.0 ile

using static System.Console;

namespace CSharpSix
{
    class Program
    {
        private static double MultiplyNumbers(double num1, double num2) => num1 * num2;

        static void Main(string[] args)
        {
            double num1 = 3;
            double num2 = 6;

            WriteLine(MultiplyNumbers(num1, num2));
            ReadLine();
        }
    }
}

 

4) Null Conditional Operator

Developerlar için kaçınılmazdır ki bir objenin veya tanımlanmış olan bir değerin "null" mı değil mi diye sürekli kontrol etme durumunda kalmışızdır ve bu kontrol için genelde min 2 satır kod yazmak zorundayızdır. if(obj!=null) ... şeklinde. C# 6.0 ile birlikte null check yapma işlemleri biraz daha kolay hale getirilmiş.

Öncesinde

using System;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            Person person = new Person();
            if (person.Name == String.Empty)
            {
                person = null;
            }

            Console.WriteLine(person != null ? person.Name : "Field is null.");
            Console.ReadLine();
        }
    }

    public class Person
    {
        public string Name { get; set; }
    }
}

C# 6.0 ile

using System;
using static System.Console;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            Person person = new Person();
            if (person.Name == String.Empty)
            {
                person = null;
            }

            WriteLine(person?.Name ?? "Field is null.");

            ReadLine();
        }
    }

    public class Person
    {
        public string Name { get; set; } = "";
    }
}

 

5) String Interpolation

String bir ifadeyi formatlayıp farklı şekilde bir string birleştirme işlemi vs yaparak göstermek itediğimizde string.format("{0} {1}","Caner", "Tosuner"); vs şeklinde tanımlıyorduk. 6.0 il birlikte bu formatları ve ifadeleri yapmak biraz daha kısa hale getirilmiş diyebiliriz. 

Öncesinde

using System;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            string firstName = "Caner";
            string lastName = "Tosuner";

            Console.WriteLine("Name : " + firstName + " " + lastName);
            Console.WriteLine("Name : {0} {1}", firstName, lastName);

            Console.ReadLine();
        }
    }
}

C# 6.0 ile

using static System.Console;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            string firstName = "Caner";
            string lastName = "Tosuner";

            WriteLine($"{firstName} {lastName} is my name!");

            ReadLine();
        }
    }
}

Bu yazım şekliyle birlikte string format yazımının karmaşasından da kurtulmuş oluyoruz.

 

6) Exception Filters

try içerisinde bir exception alınıp carch'e düştüğünde exceptiona neden olan şeyle ilgili bir spesification yapmak istediğimizde genelde catch bloğu içerisinde if(ex.Message.Equals("bişey bişey")) şeklidne yazarız. 6.0 ile catch bloğu yanına bu if condition'ları yazabilir hale geliyoruz ve her condition'nın kendi catch'i oluyor.

Öncesinde 

using System;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                throw new Exception(404);
            }
            catch (Exception ex)
            {
                if (ex.Message.Equals("500"))
                    Console.Write("Bad Request");
                else if (ex.Message.Equals("401"))
                    Console.Write("Unauthorized");
                else if (ex.Message.Equals("402"))
                    Console.Write("Payment Required");
                else if (ex.Message.Equals("403"))
                    Console.Write("Forbidden");
                else if (ex.Message.Equals("404"))
                    Console.Write("Not Found");
            }
           Console.ReadLine();
        }
    }
}

C# 6.0 ile

using System;
using static System.Console;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
               throw new Exception(404);
            }
            catch (Exception ex) if (ex.Message.Equals("400"))
            {
                Write("Bad Request");
            }
            catch (Exception ex) if (ex.Message.Equals("401"))
            {
                Write("Unauthorized");
            }
            catch (Exception ex) if  (ex.Message.Equals("402"))
            {
                Write("Payment Required");
            }
            catch (Exception ex) if (ex.Message.Equals("403"))
            {
                Write("Forbidden");
            }
            catch (Exception ex) if (ex.Message.Equals("404"))
            {
                Write("Not Found");
            }
            ReadLine();
        }
    }
}

 

7) Await in a Catch and Finally Block

C# 6. ile birlikte artık Catch ve Finally blockları arasında await keyword'ünü kullanıp asynchronous çalışan kodlar yazabiliyoruz. Daha önce bunu yapabilmemiz mümkün değildi ve ihtiyaç halinde (logging etc.) çeşitli kontroller yapıp catch bloğundan çıktıktan sonra async yapmak istediğimiz işlemi yapardık.

Öncesinde 

using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            bool isException=false;
            try
            {
                throw new notimplementedexception();
            }
            catch (Exception exception)
            {
                isException = true;
            }
             if(isException)
                 var result = await LogManager.Log("Hata oluştu !" + exception.Message);
            Console.ReadLine();
        }
    }
}

C# 6.0 ile

using System;
using System.Net.Http;
using System.Threading.Tasks;
using static System.Console;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                throw new notimplementedexception();
            }
            catch (Exception exception)
            {
                var result = await LogManager.Log("Catch => Hata oluştu !" + exception.Message);
            }
            finally
            {
                var result = await LogManager.Log("Finally => Hata oluştu !" + exception.Message);
            }            
           ReadLine();
        }
    }
}

 

8) Index initializers

Önceden bir List'e veya Dictionary'ye belirli bir index'ine item atamak istediğimizde önce initialize eder sonra nokta operatörüyle değerleri atardır. 6.0 ile birlikte initialize sırasında bu bu atam işlemlerini yapabilmekteyiz.

Öncesinde 

using System;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
           var dic = new Dictionary<int, string>
                        {
                            { 1, "one" },
                            { 4, "four" },
                            { 10, "ten" }
                        };
        }
    }
}

C# 6.0 ile

using System;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
           var dic = new Dictionary<int, string>
                          {
                             [1] = "one",
                             [4] = "four",
                             [10] = "ten"
                          };
        }
    }
}

Yukarıda 2 syntax'a baktığımızda ne fark var ki ikisi de aynı diyebiliriz ancak şöyle bir ayrım var. 6.0'dan önceki yazımda .Add() metodu kullanılarak initialize işlemi yapılıyor. Yeni syntax'da ise direkt olarak index assignments kullanılmakta ve bu da performans olarak daha verimli bir hale gelmekte. 

 

9) nameof Operatörü

Tanımlamış olduğumuz değişkenin veya objenin string olarak adına ulaşmak istediğimizde 6.0 ile birlikte gelen nameof operatörünü kullanabiliriz.

Öncesinde 

using System;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            DoSomething("Selam");
            Console.ReadLine();
        }

        public static void DoSomething(string name)
        {
            if (name == null) throw new Exception("Name is null");
        }
    }
}

C# 6.0 ile

using System;
using static System.Console;

namespace CSharpSix
{
    class Program
    {
        static void Main(string[] args)
        {
            DoSomething("Selam");
            ReadLine();
        }

        public static void DoSomething(string newName)
        {
            if (newName == null) throw new Exception(nameof(newName) + " is null");
        }
    }
}