NET Compiler Platform Roslyn
Selamlar;
Uzun süredir üzerinde çalışılan yeni Roslyn compiler projesi artık yavaş yavaş meyvesini vermeye başladı. Bugün enson Visual Studio 2014 CTP3 ile gelen Roslyn yeniliklerini inceleyeceğiz. Uzun süredir yapılmak istenen yenilikler eski compiler yüzünden yapılamıyordu. Artık yeni compiler Roslyn ile istenen yenilikler kolayca implemente edilebiliyor.
Öncelikle Visual Studio 2014’de Roslyn’in özelliklerini kullanmak için oluşturulan proje bir text editöründe açılıp alttaki satırın eklenmesi gerekmektedir.
Şimdi sıra ile gelen yeniliklere göz atalım.
- Auto-property enhancements : Propertyler’e değer atanmaması durumunda default değer atanabilmektedir.
1 2 3 4 5 6 7 8 |
public class Customer { public string FirstName { get; set; } = "Bora"; public string LastName { get; set; } = "Kaşmer"; } Customer newCustomer = new Customer(); WriteLine(newCustomer.FirstName + " " + newCustomer.LastName); |
Sonuç : Bora Kaşmer
- Parameters on classes and structs : Classlar oluşturulurken constructer olmadan parametre alması sağlanmıştır.
1 2 3 4 5 6 7 8 |
public class RealCustomer(string firstName, string lastName) { public string FirstName { get; } = firstName; public string LastName { get; } = lastName; } RealCustomer relCustomer = new RealCustomer("Duru", "Kaşmer"); WriteLine(relCustomer.FirstName + " " + relCustomer.LastName); |
Sonuç: Duru Kaşmer
- Using static : Static class’lar using olarak projeye eklenebilmektedir.
1 2 3 4 5 6 7 8 |
using System.Console; using System.Math; class Program { static void Main() { WriteLine(Sqrt(3*3 + 4*4)); } } |
- Extension methods : Extension methodlar projeye using ile eklenebilmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using System.Linq.Enumerable; class Program { static void Main(string[] args) { var range = Range(5, 17); var odd = Where(range, i => i % 2 == 1); foreach (int num in odd) { WriteLine(num); } ReadLine(); } } |
Sonuç :
- Declaration expressions : Expressionlar içerisinde artık tanımlama yapılabilmektedir. Ençok kullanıldığı yerler out parametreleridir.
1 |
int.TryParse(number, out var x); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Customer { public char[] Strings { get { return "a12b3d".ToCharArray(); } } public List<int> GetResult() { var result = (from s in Strings select int.TryParse(s.ToString(), out int i) ? i : -1).ToList(); return result; } } Customer newCustomer = new Customer(); foreach (int num in newCustomer.GetResult()) { WriteLine(num); } |
Sonuç:
- Exception filters : Yakalanan hatalara filitre konabilmektedir. Böylece belirtilen catch bloğunda sadece tanımlanan exception filtresine uygun exceptionlar yakalanır. Eğer hiçbir filitreye uymayan exception var ise stacktrace kaybolmadan işleme devam edilir. Aşağıdaki örnekte de görüldüğü gibi number değeri 50’den küçük olduğu için en sondaki catch’e düşmekte ve 1 değerini döndürmektedir. Eğer number 50’den büyük olur ise ilk cathc’e düşmekte ve geriye number’ın kendi değeri döndürülmektedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class Point(int x, int y) { string number = "45"; public int GetNumber() { try { int.TryParse(number, out var x); throw new Exception(); return x; } catch (Exception e) if (int.Parse(number) > 50) { return number; } catch (Exception e2) { return 1; } } } |
Sonuç: 1
- Await in catch and finally blocks : Try ve catch blokları arasında asenkron methodlar işletilebilmektedir. Aşağıdaki örnekte görüldüğü gibi hata fırlatılmış ve number 50’den küçük olduğu için ikinci catch bloğuna gidilmiştir.Burada borakasmer.com’ sitesine asenkron olarak gidilip sitenin string karakter sayısı geriye döndürülmüştür
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public class Point(int x, int y) { string number = "45"; public int GetNumber() { try { int.TryParse(number, out var x); throw new Exception(); return x; } catch (Exception e) if (int.Parse(number) > 50) { return 1; } catch (Exception e2) { int result = AccessTheWebAsync().Result; return result; } } public int Age { get; set; } = 36; async Task<int> AccessTheWebAsync() { HttpClient client = new HttpClient(); Task<string> getStringTask = client.GetStringAsync("http://www.borakasmer.com/net-compiler-platform-roslyn/"); string urlContents = await getStringTask; return urlContents.Length; } } |
- Null-conditional operators : Herhangi bir class veya propertyleri null ise bunlara erişmek için null kontrolü yapmadan çok daha basit yolla değerleri çekebiliriz.
1 |
int? first = (customers != null) ? customers[0].Orders.Count() : null; |
Yukarıdaki kodun yerine aşağıdakini kullanabiliriz.
1 |
int? first = customers?[0].Orders?.Count(); |
Böylece eski compiler’dan kurtulunca artık neler yapabileceğimizi gördük. Daha birçok yeniliğin kapıda olduğunu belirtir bloğumu takip etmenizi tavsiye ederim.
Detaylı Pdf: http://www.borakasmer.com/projects/ctp3-csharp-features.pdf
Geldik bir makalenin daha sonuna.
Herkese hoşçakalın.
Source:
Aslında açık kaynaklı yazılım dünyasında 20 senedir olan imkanların C# dünyasına gelmesi bu. En basitinden örnek, Roslyn’in Read-Eval-Print Loop özelliği Ruby veya Python gibi dillerde irb ve IPhyton adları altında 10+ yıldır vardı. Ayrıca Ruby DSL Embedding alanında büyük yaygınlık kazandı. Fakat “derleyici” konusunda hepsinin (günümüzde dahi) lideri LISP’tir çünkü tum bu yukarda verilen özellikleri 20 yıldır LISP zaten kullanıyordu. Yine en basitinden örnekle ” Propertyler’e değer atanmaması durumunda default değer atanabilmesi” konusunda LISP, fonksiyon argümanları arasında &optional parametresini kullanmaktadır, böylelikle herhangi bir argüman isteğe bağlı olarak verilebilir veya verilmeyebilir veya default değer olarak da verilebilir. Tüm bunlar LISP’in 1990 implementasyonunda vardı :) Daha bitmedi, C#’ta “Generics” olarak gündeme gelen, tip belirtme zorunluluğu olmayan değişken/sınıf tanımlama imkanı da LISP’te 1980’lerden beri vardı, cunku LISP’te değişkenlerin integer, string gibi tipi yoktur, değişkenler ancak değer atandıktan sonra tipe sahip olurlar. Aynı durum tabi ki sınıflar için de geçerlidir.
Tüm bunlardan sonra C# ‘ın bu yenilikleri içermeye başladığını görmek çok güzel bir olay cunku programlama dünyasındaki ufku açıyor. Ancak yine de C# ‘nin ağdalı syntax yapısı yüzünden Ruby gibi pratik ve kısa olması güç.