C# 9 ile Gelecek Yenilikler
Geçtiğimiz haftalarda pandemi nedeniyle online düzenlenen Microsoft Build 2020 etkinliğinde birçok yenilik duyurusu yapıldı. Biz yazılım geliştiricilerin en ilgisini çekenlerden biri belki de C# 9 ile hangi yeniliklerin geleceğiydi. Build etkinliğinde duyurulan yeni C# dil özelliklerinden bazılarını bu makalede ele alıp inceleyeceğiz. Elbette gelecek olan yenilikler bu makalede anlatılanlarla sınırlı değil ve bazı yeniliklerin eklenip çıkarılabileceğini biliyoruz. Şunu hatırlatmakta fayda var; bu yazı Haziran 2020’de yazıldı ve henüz resmi bir C# 9 sürümü çıkmadı. Yazıda sadece Build etkinliğinde duyurulan ve yakın gelecekte karşımıza çıkması kuvvetle muhtemel C# 9 dil özelliklerinden bazılarına göz atacağız.
Yeni gelecek özellikleri şu başlıklar altında inceleyelim:
Target-type new
Bildiğiniz üzere sınıflar referans tiplerdir. Bir sınıfın örneğini almak için new operatörü kullanırız. C# 9‘dan önce bir sınıfın örneğini almak için aşağıdaki tanımlamayı yapmamız gerekiyordu.
List customerNames = new List();
C# 9 ile beraber artık new operatörünü kullandıktan sonra bir tip belirtmemize gerek kalmıyor. Aşağıdaki tanımlama ve yukarıdaki tanımlama aslında aynı şeyi ifade etmekte. var keyword’ünün eşittir operatörünün sağ tarafına geçmiş haline benzetebiliriz sanırım bu kullanımı.
List<string> customerNames = new();
Parameter null checking
C# 9 ile gelecek bir diğer kullanışlı özellik ise metot parametreleri ile ilgili olacak. Bir metot tanımladığımızda metot parametrelerinin null check yapmak için fazladan en az 2 satır eklememiz gerekiyordu. C# 9 öncesinde metot parametresi için yazılmış null checking örneğini alttaki kod parçasında görebilirsiniz:
public void PrintMessage(string message) { if(string.IsNullOrEmpty(message)) throw new ArgumentNullException(nameof(message)); Console.WriteLine(message); }
C# 9 ile birlikte gelen parameter null checking özelliğiyle üstteki kodda yer alan if bloğunu yazmaya gerek kalmıyor. Bunun için null check yapmak istenen parametre değişken adının sonuna ! (ünlem işareti) eklemek yeterli olacaktır.
public void PrintMessage(string message!) => Console.WriteLine(message);
Target-typed conditional expressions
Ternary operator ( ?: ) olarak bildiğimiz ve tek satırda if-else yerine kullanabildiğimiz bu ifade şeklinde eskiden ? ve : sonra aynı tipten değer yazma zorunluluğu vardı. C# 9 ile bu zorunluluk ortadan kalkıyor ve if ve else şartları sağlandığında iki farklı tipten değer yazılabiliyor. Örneğin aşağıdaki kullanımda ?’den sonra string, :’den sonra ise DateTime tipinden değer kullanılıyor.
DateTime? deliveredDate = string.IsNullOrEmpty(input) ? "" : DateTime.Now;
Covariant return
C# ile uygulama geliştirirken bir sınıf başka bir sınıftan inherit olduğunda ve base sınıfın bir metodunu override ettiğinizde, o metodun dönüş tipi base sınıftaki metodun dönüş tipiyle aynı olmak zorundaydı. Bu durum C# 9 ile birlikte değişti ve artık override edilen metodların base sınıftaki metottan farklı dönüş tipine sahip olmasına olanak tanındı.
Bu kulağa ilk başta kullanışsız gelse de aslında işin detayına inince mantıklı hale geliyor. Örnek olarak Car sınıfından ya da ICar interface’inden türemiş herhangi bir sınıfı override ettiğiniz bir metotda geriye döndüremezsiniz. Override edilen metot ile base metodun dönüş tipi birebir aynı olmak zorundaydı. Ancak C# 9 ile Car sınıfından ya da ICar interface’inden türemiş bir sınıfı geriye döndürmemiz mümkün. Bu da bize kontrollü bir şekilde serbestlik kazandırıyor. Örnek olarak aşağıdaki gibi bir senaryo düşünebiliriz.
public class CarList { public virtual Car Car() => new Car(); } public class PickupList : CarList { public override Pickup Car() => new Pickup(); } public class Car {} public class Pickup : Car {}
Normalde bu işlemi yaptığımızda ‘PickupList.Car()': return type must be ‘Car’ to match overridden member ‘CarList.Car()’ hatasını alırız ancak C# 9 ile bu sorun ortadan kalkmış oluyor.
Top-level statements
Bu yenilik bilhassa Console’da çalışan basit ve küçük programlar yazma durumlarında oldukça kullanışlı. Normalde bir C# uygulaması yazarken, kodların mutlaka bir sınıf ve metot içerisinde yer alması gerekmektedir. Ancak bu yeni özellikle sınıf ve metot yazma zorunluluğu ortadan kalkıyor. Örneği alttaki kod parçası, C# 9 öncesinde basit bir Console uygulamasında ekrana yazı yazmamızı sağlayan minimum yazılabilecek kod parçasıydı.
public class Program { public void Main() { Console.WriteLine("Hello World"); } }
C# 9 ile basit bir console uygulaması çalıştırmak ve ekrana bir şey yazmak isterseniz artık aşağıdaki kod parçası artık işinizi görebilecek. Tabii ki uygulama büyüdüğünde artık metot ve sınıf kullanımı zorunlu hale gelecektir ama kısa koddan oluşan basit uygulamalar için kolaylaştırıcı bir yenilik.
using System; Console.WriteLine("Hello world");
Extending Partial Methods
Bu özelliğin amacı partial sınıf ve metotlardaki kısıtlamaların ortadan kaldırılması diyebiliriz. Örnek olarak bir partial metotların dönüş tiplerinin void olması gerekiyordu. Bu gelecek olan özellik ile böyle bir zorunluluk ortadan kalkmış oldu.
Bir diğer kısıtlama ise erişim belirleyicilerin kullanılmasıyla alakalıydı. Partial metotlarda herhangi bir erişim belirleyici kullanamıyorduk. Bunun yanı sıra override, sealed, virtual, abstract gibi tanımlamaları da yapamıyorduk. Bu özellik, partial metotlarda az önce saydığım tanımlamaları yapmamıza imkan sağlıyor. En nihayetinde partial sınıf ve metotları aşağıdaki gibi kullanabileceğiz.
interface IStudent { string GetName(); } partial class CollegeStudent : IStudent { public virtual partial string GetName(); } partial class CollegeStudent { public virtual partial string GetName() => "John Doe"; }
Bir diğer kısıtlama ise partial metotlarda ref ve out parametrelerin kullanılamamasıyla alakalıydı. Bu konudaki kısıtlamalar da ortadan kalkarak aşağıdaki gibi bir kullanıma olanak sağlanmış oldu
partial class CommonHelper { internal partial bool TryParse(string s, out int i); } partial class CommonHelper { internal partial bool TryParse(string s, out int i) { } }
Pattern matching improvements
Yine basit ama kullanışlı bir yenilik. İlk olarak not operatorüne göz atalım. Bir nesnenin belirli bir tipte olup olmadığını is operatörü ile kontrol ediyoruz bildiğiniz gibi. Örneğin object tipinde olan ve içinde Honda sınıfından bir nesne varsa, bu nesnenin Honda sınıfından olup olmadığını “nesneAdi is Honda” şeklindeki sonucu boolean olan bir ifadeyle kontrol edebiliyoruz. Ancak bu ifadenin tersini eskiden kullanamıyorduk, yani “is not” ifadesi yoktu. Ama C# 9 ile artık böyle bir kullanım mümkün olacak.
if(selectedCar is not Honda) Console.WriteLine("Seçtiğiniz araç Honda tipinden bir nesneye ait değil.");
İlişkisel ve mantıksal operatörler de artık pattern matching işlemi için kullanılabilir durumda. Bunun için de bir senaryo hayal edelim. Diyelim ki sağlık sektöründe çalışıyorsunuz. Çalıştığınız kurumda gelen hastaların yaş gruplarına göre tedavi görebilecekleri farklı bölümler var. Siz bu yaş aralıklarını Enum oluşturup kategorize etmek ve buna göre işlem yapmak istiyorsunuz diyelim. O zaman C# 9 ile aşağıdaki gibi bir metot yazabilirsiniz.
public static LifeStage LifeStageAtAge(int age) => age switch { < 0 => LiftStage.Prenatal, < 2 => LifeStage.Infant, < 4 => LifeStage.Toddler, < 6 => LifeStage.EarlyChild, < 12 => LifeStage.MiddleChild, < 20 => LifeStage.Adolescent, < 40 => LifeStage.EarlyAdult, < 65 => LifeStage.MiddleAdult, _ => LifeStage.LateAdult, };
Umarım yeni özellikler hakkında sizlere faydalı bilgiler verebilmişimdir. C# 9 ile gelecek özelliklerin tamamını aşağıdaki linke tıklayıp inceleyebilirsiniz. Herhangi bir sorunuz ya da görüşünüz için bana yazar bilgilerimde yer alan sosyal medya hesaplarımdan ulaşabilirsiniz.
Kaynaklar : https://github.com/dotnet/roslyn/blob/master/docs/Language%20Feature%20Status.md