Bir önceki yazıda C# 9.0'ın teması olan immutable data ile çalışma yeniliklerinden bahsetmiştik. Bu yazıda ise C# 9.0 içerisinde yer alan diğer yeniliklere bakacağız. Vakit kaybetmeden incelemeye hızlıca başlayalım.
Target-typed new expressions
Bir nesne yaratılırken eğer nesne tipi tahmin edilebiliyorsa constructor çağırma öncesinde tip belirtilmesi artık zorunlu olmayacak. Özellikle parametre sayısı fazla olan generic tiplerden nesne yaratırken yazılan uzun kodların önüne geçilebilir.
Örneğin,
List<string> list = new List<string>();
Burada nesnenin tipi sol taraftaki tanımlamadan tahmin edilebileceği için aşağıdaki gibi bir kullanım mümkün olacak.
List<string> list = new();
Parameter null Checking
Metotlara geçilecek olan parametrelerin null kontrolü parametrenin sonuna eklenecek olan ! işaretiyle artık otomatik bir şekilde yapılabilecek.
Örneğin,
public void DoWork(Person person) { if (person == null) { throw new ArgumentNullException(nameof(person)); } }
Bu şekilde null kontrolü yapmak yerine aşağıdaki gibi tanımlamayla bu işlemi otomatik bir hale getirebiliriz.
public void DoWork(Person person!) { }
Lambda discard parameters
C# 9.0 ile beraber lambda parametrelerini de discard edebiliyoruz.
Func<int, int, string> func = (_, _) => string.Empty;
Static Lambdalar
C# 9.0 ile beraber lambdaları artık statik olarak tanımlayabiliyoruz. Lambdaları statik olarak tanımladığımızda lambdalar lokal değişkenlere, this veya base'e ulaşamadığı için ekstra bir heap allocationa sebep olmuyorlar. Statik olmayan lambdalarda bu durumlar gözden kaçabildiği için statik olarak tanımladığımızda erişim gerçekleştiği durumda compiler derleme hatası vereceği için bu hataların önüne geçmemiz oldukça kolay.
//Lambda static olarak tanımlandığı için kod derlenirken hata alınacak. int x; DoWork(static (_, _) => x.ToString());
Target-Typed Conditional Expression
Conditional expressionlarda eğer tipler arasında ortak bir tip varsa veya implicit olarak çevrim yapılabiliyorsa compiler artık bu işlemi arka planda otomatik olarak yapıyor ve derleme hatası alınmıyor.
Aşağıdaki kodlar C# 9.0 öncesinden derleme hatası verirken C# 9.0 ile beraber artık derlenebilmekte.
Person p = customer ?? student; // Ortak base tip int? x = person == null ? 0 : null; //nullable value type
Top-level Statements
Başlarda ne gerek vardı dediğim ama kullandıkça bağımlısı olduğum bir özellik 😃 Bugün basit bir uygulama yazabilmemiz için bile bir Main metot tanımlamamız ve onun içerisine de kodumuzu yazmamız gerekmekte. Basit bir uygulama için bile yazılması gereken boilerplate kod oldukça fazla. C# 9.0 ile beraber artık bu boilerplate koda gerek kalmadan çalışacak kodu yazabiliyoruz. Ana çalışacak kod using ifadeleri ile namespace veya class tanımlaması arasında olmalı.
using System; class Program { public static void Main() { var person = new Person() { FirstName = "Ilkay", LastName = "Ilknur" }; Console.WriteLine($"{person.FirstName} - {person.LastName}"); } } public class Person { public string FirstName { get; set; } public string LastName { get; set; } }
Bu kodu artık C# 9.0 ile beraber şu hale getirebiliriz.
using System; var person = new Person() { FirstName = "Ilkay", LastName = "Ilknur" }; Console.WriteLine($"{person.FirstName} - {person.LastName}"); public class Person { public string FirstName { get; set; } public string LastName { get; set; } }
Covariant returns
Bu özellikle beraber artık programlama dili override edilen metodun dönüş tipinin daha derived tip olmasına izin vermekte.
Örneğin,
public abstract class Car { public abstract Car Do(); } public class SportsCar : Car { public override SportsCar Do() { } }
Pattern Matching Yenilikleri
C# 9.0 ile beraber pattern matching tarafında da iyileştirmeler ve yenilikler bulunmakta.
Type Pattern İyileştirmeleri
C# 9.0 öncesinde sadece type check yapmak için aynı zamanda identifier tanımlamak veya discard _ kullanmak gerekiyordu. C# 9.0 ile beraber artık tanımlama yapmaya gerek kalmayacak.
C# 9.0 öncesi
switch (person) { case Student s: DoSomething(); break; case Customer c: DoSomething2(); break; }
C# 9.0 ile beraber şu şekilde yazabiliriz.
switch (person) { case Student: DoSomething(); break; case Customer: DoSomething2(); break; }
Relational Patterns
C# 9.0 ile beraber relational patternler (<,>,<=,>=)
de dile eklenmis oluyor.
Örneğin,
int discount = person.Age switch { <= 18 => 20, <= 30 => 10, _ => 0 };
Logical Patterns
Pattern combinators da diyebileceğimiz bu yenilikle beraber farklı patternleri and, or veya not
gibi ifadelerle birleştirebiliyoruz.
int discount = person.Age switch { <= 18 => 20, > 18 and <= 30 => 10, _ => 0 }; int price; if (person is not Student) { price = 200; } else { price = 100; }
Diğer Yenilikler
C# 9.0 ile beraber gelen diğer yeniliklerin listesi ise şu şekilde.
Partial metotlardaki kısıtlamalar ortadan kaldırılıyor. Böylece code generation yapılan Windows Forms gibi platformlarda developerların bazı senaryolarda otomatik olarak generate edilen kodları editlemesinin önüne geçiliyor : https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/extending-partial-methods.md
C# 9.0 ile beraber function pointer tanımlamak mümkün olabilecek. Özellikle yüksek performans gerektiren senaryolarda kullanılabilir. https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/function-pointers.md
Local functionlarda attribute artık kullanmak mümkün olacak. https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/local-function-attributes.md
Module(Assembly) initializationında yaşanan bazı sorunların çözülmesi amacıyla programlama dili tarafında bu özelliğe destek geliyor: Detaylı bilgi için proposalı inceleyebilirsiniz. https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/module-initializers.md
native-sized signed ve unsigned integer tipleri için dil desteği geliyor. https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/native-integers.md
Bir sonraki yazıda görüşmek üzere,
Kaynak : https://github.com/dotnet/csharplang/tree/master/proposals/csharp-9.0