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