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"); } } }