İlkay İlknur

C# 9.0 İle Beraber Gelen Diğer Yenilikler

Eylül 04, 2020

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<intintstring> 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 { getset; }
    public string LastName { getset; }
}

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 { getset; }
    public string LastName { getset; }
}

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.

Bir sonraki yazıda görüşmek üzere,

Kaynak : https://github.com/dotnet/csharplang/tree/master/proposals/csharp-9.0