C# 9

Paylaş

C# 9 ile birlikte gelen Record, Top-level statements, Pattern matching enhancements, Covariant return types, Function Pointers yenilikleri C# kod örnekleri ile birlikte yer alıyor.

C# 9 ile gelen özelliklere bakmadan önce C# 8 ile gelen özelliklere buradan bakabilirsiniz.

Init-only Properties

Özellik değişmez-immutable nesne oluşturmayı initializer {} ile sağlar.

using System;

class Person {
    public Guid Id { get; } = Guid.NewGuid();
    public string FirstName { get; init; } // Init-only properties
    public string LastName { get; init; } // Init-only properties
    public override string ToString() {
        return $"{Id} {FirstName} {LastName}";
    }
}

class Program {
    public static void Main(string[] args) {
        Person person = new Person { FirstName = "Yusuf", LastName = "Sezer" }; // initializer
        Console.WriteLine(person);
    }
}

Özelliğin set ifadesinden farkı sadece initializer ve değerinin değiştirilememesidir.

Records

Özellik değişmez-immutable referans türleri oluşturmayı daha kısa ve etkili olarak aşağıdaki gibi sağlar.

using System;

record Person(string FirstName, string LastName) {
    public Guid Id { get; } = Guid.NewGuid();
    public override string ToString() {
        return $"{Id} {FirstName} {LastName}";
    }
}

class Program {
    public static void Main(string[] args) {
        Person person = new Person("Yusuf", "Sezer");
        Console.WriteLine(person);
        (var firstName, var lastName) = person; // Deconstruct
        Console.WriteLine($"{firstName} {lastName}");
    }
}

NOT: Veriler tutmak için kullanılan records Value equality sayesinde benzer değere sahip referans değerler için doğru-true olarak çalışır.

Top-level statements

Özellik her C# uygulamasında zorunlu olarak kullanılan Main metodunu arka planda yaparak kısa ve özlü kod yazmayı sağlar.

using System;

System.Console.WriteLine("Yusuf Sezer"); // Using kullanılmadan

for (int i = 0; i < args.Length; i++) {
    Console.WriteLine($"{i} -> {args[i]}"); // Using kullanarak
}

Pattern matching enhancements

C# 7 ile birlikte gelen Pattern matching özelliğine Pattern Combinators (and, or, not) ve Relational Patterns (<, <=, >, >=) gibi özellikler eklenmiştir.

using System;

int day = Convert.ToInt32(DateTime.Now.DayOfWeek);
var isHoliday = day switch {
    <= 0 or >= 6 => true, // Pattern Combinators - and, or ve not
    >= 1 or <= 5 => false // Relational Patterns
};

var name = "Yusuf Sezer";
if (name is not null) { // Pattern Combinators
    Console.WriteLine(name);
}

Native Integers

Özellik düşük seviyeli, performans gerektiren kütüphaneler için işletim sistemi mimarisine(32-64) göre işaretli (System.IntPtr) ve işaretsiz (System.UIntPtr) veri tipini sağlar.

nint x = -3;
nuint y = 3;

System.Console.WriteLine($"{x} {x.GetType()}");
System.Console.WriteLine($"{y} {y.GetType()}");

Function Pointers

Özellik fonksiyon veya metot adreslerini delegate yapısından farklı olarak doğrudan – IL olmadan erişmeyi sağlayarak performansı artımayı amaçlar.

using System;

unsafe {
    Math.Hesapla(&Toplama, 10, 20);
}

static int Toplama(int a, int b) {
    return a + b;
}

unsafe class Math {
    public static void Hesapla(delegate*<int, int, int> f, int a, int b) {
        delegate*<int, void> Yazdir = &EkranaYazdir; // & referans
        int sonuc = f(a, b);
        Yazdir(sonuc);
    }

    private static void EkranaYazdir(int neyi) {
        Console.WriteLine(neyi);
    }
}

C# delegate hakkında detaylı bilgi için C# delegate Nedir? Kullanımı yazıma bakmalısın.

Target-typed new expressions

Özellik var anahtar kelimesinin tam tersi olarak hedef tür için ayrıca tür belirtmeden new anahtar kelimesiyle sağlar.

using System;
using System.Collections.Generic;

object obj = new();
Console.WriteLine(obj);

List<string> names = new() { "Yusuf", "Sefa", "Sezer" };
Console.WriteLine(string.Join(", ", names));

Person person = new("Yusuf", "Sezer");
Console.WriteLine(person);

record Person(string FirstName, string lastName);

Static anonymous functions

Özellik yerel değişkenlere erişimi kısıtlamak için static anahtar kelimesini lambda ifadelerinde kullanmayı sağlar.

using System;

int benimSayim = 1453;

Action<int> yazdirNormal = (int neyi)
    => Console.WriteLine(benimSayim + neyi);
yazdirNormal(0);

//Action<int> yazdirStatik = static (int neyi)
//    => Console.WriteLine(benimSayim + neyi); // Yerel-local değişkenlere erişemez.
//yazdirStatik(0);

Target-Typed Conditional Expression

Özellik aşağıdaki örnekte null ifadesi hedef tür olan int ifadesine ilave çevrim-cast ihtiyaç duyulmadan yapar.

using System;

class Program {
    public static void Main(string[] args) {
        string name = Console.ReadLine();
        int? length = string.IsNullOrWhiteSpace(name) ? null : name.Length;
        Console.WriteLine("Uzunluk: {0}", length);
    }
}

NOT: C# 9 öncesinde null ifadesi hedef türe dönüştürmeye isteyecektir.

Covariant returns

Özellik ezilen metotlardaki-override dönüş türünden, genişleyen dönüş türünü kullanmayı çevrim-cast olmadan sağlar.

using System;

abstract class Hayvan {
    public abstract Yemek GetFood();
}

class Kaplan : Hayvan {
    public override Et GetFood() => new Et(); // Covariant returns
}

class Kedi : Hayvan {
    public override Sut GetFood() => new Sut(); // Covariant returns
}

public class Yemek { }

public class Et : Yemek {
    public Et() => Console.WriteLine("Ben et yerim.");
}

public class Sut : Yemek {
    public Sut() => Console.WriteLine("I drink milk...");
}

class Program {
    static void Main(string[] args) {
        Kaplan kaplan = new Kaplan();
        Kedi kedi = new Kedi();

        Et et = kaplan.GetFood();
        Sut sut = kedi.GetFood();
    }
}

Extension GetEnumerator

Özellik IEnumerator arayüzüne eklenen extension metot sayesinde IEnumerator arayüzünü foreach döngülerinde kullanmayı sağlar.

using System.Linq;
using System;
using System.Collections.Generic;

foreach (var num in Enumerable.Range(0, 10).GetEnumerator()) {
    Console.WriteLine(num);
}

public static class Extensions {
    public static IEnumerator<T> GetEnumerator<T>(this IEnumerator<T> enumerator) => enumerator;
}

Lambda discard parameters

Özellik lambda ifadelerinde kullanılmayan parametreler yerine alt çizgi-discard (_) ifadesini kullanmayı sağlar.

using System;

Action<int, int> myAction = (_, _) => Console.WriteLine("Yusuf Sezer");
Func<decimal, long, string> MyName = delegate (decimal _, long _) { return "Yusuf Sezer"; };
myAction(10, 10);
string name = MyName(10, 20);
Console.WriteLine(name);

Attributes on local functions

Özellik C# 7 ile birlikte gelen local functions özelliğine nitelik-attribute eklemeyi sağlar.

using System;

LocalFunction();

[Obsolete("Bu fonksiyon artık kullanılmamaktadır.")]
void LocalFunction() {
    Console.WriteLine("Yusuf Sefa Sezer");
}

Module Initializers

Özellik modül-assembly başlangıcı için ModuleInitializer nitelik-attribute sağlar.

using System;
using System.Runtime.CompilerServices;

Console.WriteLine("Merhaba C# 9");

class Modul {
    [ModuleInitializer]
    public static void Giris() => Console.WriteLine("Yusuf Sezer");
}

Extending Partial Methods

Özellik partial metotlar için var olan void zorunlu dönüş, parametrelerde out anahtar kelime kullanımı ve erişim belirteci (public, private vs.) kısıtını kaldırır.

System.Console.WriteLine(Util.Uzunluk("Yusuf Sezer"));

partial class Util {
    public static partial int Uzunluk(string neyin);
}

partial class Util {
    public static partial int Uzunluk(string neyin) => neyin.Length;
}

C# 9 sürümü önceki sürümlerde gelen özelliklerin genişletilmesinin yanında Record, Top-level statements ve Target-typed new expressions özellikleri ile daha kod ile daha fazla iş yapmayı sağlamıştır.

C# 9 sürümünü kullanmak için .csproj dosyasında <LangVersion>9.0</LangVersion> ifadesini kullanımı yeterli olacaktır.

Yeni gelen özellikleri .NET 5 ve roslyn derleyicisi ile kullanabilirsiniz.

.NET Derslerine buradan ulaşabilirsiniz.

Hayırlı günler dilerim.


Bunlarda ilgini çekebilir